diff --git a/.gitignore b/.gitignore index 1946f23..1468982 100755 --- a/.gitignore +++ b/.gitignore @@ -128,9 +128,3 @@ dmypy.json # Pyre type checker .pyre/ - -# Binary outputs and figures (use git add -f to force-add specific files) -*.png -*.pdf -*.npy -!figs/*.png diff --git a/README.md b/README.md index 30c547f..b94cd24 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -[![Build and Test](https://github.com/CheerfulUser/TESSreduce/actions/workflows/build.yml/badge.svg)](https://github.com/CheerfulUser/TESSreduce/actions/workflows/build.yml) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![DOI](https://img.shields.io/badge/DOI-10.3847%2F1538--3881%2Fac2c2e-blue.svg)](https://doi.org/10.3847/1538-3881/ac2c2e) +[![Build and Test [Python 3.7, 3.8, 3.9]](https://github.com/CheerfulUser/TESSreduce/actions/workflows/build.yml/badge.svg)](https://github.com/CheerfulUser/TESSreduce/actions/workflows/build.yml) ![plot](./figs/header.png) diff --git a/development/.C0/tess/tess_fit_ch0.png b/development/.C0/tess/tess_fit_ch0.png new file mode 100755 index 0000000..863747d Binary files /dev/null and b/development/.C0/tess/tess_fit_ch0.png differ diff --git a/development/.C0/tess/tess_fit_ch0_residual.png b/development/.C0/tess/tess_fit_ch0_residual.png new file mode 100755 index 0000000..e291534 Binary files /dev/null and b/development/.C0/tess/tess_fit_ch0_residual.png differ diff --git a/development/2018gft.png b/development/2018gft.png new file mode 100755 index 0000000..6b3874e Binary files /dev/null and b/development/2018gft.png differ diff --git a/development/2020akf.png b/development/2020akf.png new file mode 100755 index 0000000..6eefc97 Binary files /dev/null and b/development/2020akf.png differ diff --git a/development/ApvsPSF_2023bee.png b/development/ApvsPSF_2023bee.png new file mode 100644 index 0000000..ed9d1f6 Binary files /dev/null and b/development/ApvsPSF_2023bee.png differ diff --git a/development/Untitled.ipynb b/development/Untitled.ipynb deleted file mode 100644 index b8c5271..0000000 --- a/development/Untitled.ipynb +++ /dev/null @@ -1,15639 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "6a380b77", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import tessreduce as tr\n", - "%matplotlib notebook" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "5fa94b04", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", - "made source mask\n", - "calculating background\n", - "adaptive bkg\n", - "background subtracted\n", - "aligning images\n", - "[SepAligner] 7 sources selected for alignment\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n", - "adaptive bkg\n", - "background correlation correction\n", - "field calibration\n", - "target is above -30 dec, calibrating to PS1 photometry.\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess = tr.tessreduce(tpf='../../SN_individual/grb_test.fits',\n", - " calibrate=True,quality_bitmask='hard',diagnostic_plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "f052bd1e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Optimal PSF shift: [-0.8 -0.40219973]\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "l, s = tess.diff_lc(phot_method='psf',plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "07ba73a0", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.lc[0],tess.lc[1])\n", - "plt.plot(l[0],l[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "d4308213", - "metadata": {}, - "outputs": [], - "source": [ - "tess.lc[1] += 5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d93c7118", - "metadata": {}, - "outputs": [], - "source": [ - "tess.to_flux()" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "3db708d2", - "metadata": {}, - "outputs": [], - "source": [ - "m = tess.to_mag()" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "fc31fc0c", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "ename": "NameError", - "evalue": "name 'm' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[15], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m plt\u001b[38;5;241m.\u001b[39mfigure()\n\u001b[0;32m----> 2\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(\u001b[43mm\u001b[49m[\u001b[38;5;241m1\u001b[39m])\n\u001b[1;32m 3\u001b[0m plt\u001b[38;5;241m.\u001b[39mgca()\u001b[38;5;241m.\u001b[39minvert_yaxis()\n", - "\u001b[0;31mNameError\u001b[0m: name 'm' is not defined" - ] - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(m[1])\n", - "plt.gca().invert_yaxis()" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "c46ace7f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(3, 3372)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "beca2db4", - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "50a436ad", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
MJDmJye_mJy
060774.795080-6.434997204.177252
160774.79739541.964531223.303671
260774.79971024.902475273.997902
360774.80202519.867867257.708383
460774.8043405.679091236.001919
............
836460802.251069-2.826644353.741833
836560802.253384-49.028253363.900099
836660802.255699-12.546486302.314057
836760802.258014-38.629566335.972191
836860802.260329-108.062144304.738969
\n", - "

8369 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " MJD mJy e_mJy\n", - "0 60774.795080 -6.434997 204.177252\n", - "1 60774.797395 41.964531 223.303671\n", - "2 60774.799710 24.902475 273.997902\n", - "3 60774.802025 19.867867 257.708383\n", - "4 60774.804340 5.679091 236.001919\n", - "... ... ... ...\n", - "8364 60802.251069 -2.826644 353.741833\n", - "8365 60802.253384 -49.028253 363.900099\n", - "8366 60802.255699 -12.546486 302.314057\n", - "8367 60802.258014 -38.629566 335.972191\n", - "8368 60802.260329 -108.062144 304.738969\n", - "\n", - "[8369 rows x 3 columns]" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "l = pd.DataFrame(data=tess.lc.T,columns=['MJD','mJy','e_mJy'])\n", - "l.to_csv('',index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "a795f120", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "91" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "obs[0][2]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6ebadf5d", - "metadata": {}, - "outputs": [], - "source": [ - "-2.5*np.log10(flux) + 16.4" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "f96e035f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([28.15623389, 27.60744131, 25.56201544, ..., 6.63977483,\n", - " 3.76882935, 7.28402827])" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.lc[2]" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f6d3b8db", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "!!! WARNING no MJD time specified, using default of 59000\n", - "| Sector | Camera | CCD | Covers | Time difference |\n", - "| | | | | (days) |\n", - "|----------+----------+-------+----------+--------------------|\n", - "| 91 | 4 | 3 | False | 1774.79 |\n", - "| 92 | 1 | 4 | False | 1802.47 |\n" - ] - } - ], - "source": [ - "obs = tr.spacetime_lookup(268.577,-29.122)\n", - "# obs = tr.spacetime_lookup(268.577,-29.122)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "2ebeb5e7", - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Downloading TPF from TESScut\n", - "made reference\n", - "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", - "made source mask\n", - "calculating background\n", - "adaptive bkg\n", - "background subtracted\n", - "aligning images\n", - "[SepAligner] 6 sources selected for alignment\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n", - "adaptive bkg\n", - "background correlation correction\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess = tr.tessreduce(obs_list=obs[0],size=50,\n", - " calibrate=False,quality_bitmask='hard',align=True,diagnostic_plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "b16c9ebc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(3, 8369)" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.lc.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "f0b302b9", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.bkg[:,20,20],'.')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fbd34396", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.2" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/development/Updating_getref.ipynb b/development/Updating_getref.ipynb index 49be3ed..f43d3f9 100755 --- a/development/Updating_getref.ipynb +++ b/development/Updating_getref.ipynb @@ -3,7 +3,7 @@ { "cell_type": "code", "execution_count": 1, - "id": "22ef21ec", + "id": "a94e2ce9", "metadata": {}, "outputs": [], "source": [ @@ -14,7 +14,7 @@ { "cell_type": "code", "execution_count": 2, - "id": "6c96c5fa", + "id": "9de9311b", "metadata": {}, "outputs": [ { @@ -995,7 +995,7 @@ { "cell_type": "code", "execution_count": 3, - "id": "f6c24636", + "id": "f418ce3d", "metadata": {}, "outputs": [ { @@ -1016,7 +1016,7 @@ { "cell_type": "code", "execution_count": 6, - "id": "7ab556ec", + "id": "035d6917", "metadata": {}, "outputs": [ { @@ -1992,7 +1992,7 @@ { "cell_type": "code", "execution_count": 39, - "id": "91828f2b", + "id": "2f3679a1", "metadata": {}, "outputs": [ { @@ -2968,7 +2968,7 @@ { "cell_type": "code", "execution_count": 41, - "id": "e38adc34", + "id": "3c4982fe", "metadata": {}, "outputs": [ { @@ -3944,7 +3944,7 @@ { "cell_type": "code", "execution_count": 12, - "id": "ce8361d2", + "id": "20dd67fe", "metadata": {}, "outputs": [], "source": [ @@ -3954,7 +3954,7 @@ { "cell_type": "code", "execution_count": 21, - "id": "06a6fd12", + "id": "da3b6eb0", "metadata": {}, "outputs": [ { @@ -4940,7 +4940,7 @@ { "cell_type": "code", "execution_count": 16, - "id": "335257f2", + "id": "0fe03e67", "metadata": {}, "outputs": [ { @@ -5916,7 +5916,7 @@ { "cell_type": "code", "execution_count": 19, - "id": "b3681bf4", + "id": "d62aea2e", "metadata": {}, "outputs": [ { @@ -6892,7 +6892,7 @@ { "cell_type": "code", "execution_count": 41, - "id": "8736454b", + "id": "9900a3cf", "metadata": {}, "outputs": [], "source": [ @@ -6910,7 +6910,7 @@ { "cell_type": "code", "execution_count": 42, - "id": "4fe60930", + "id": "8fb2a580", "metadata": {}, "outputs": [ { @@ -7887,7 +7887,7 @@ { "cell_type": "code", "execution_count": 48, - "id": "19e24d2d", + "id": "e8475ce4", "metadata": {}, "outputs": [], "source": [] @@ -7895,7 +7895,7 @@ { "cell_type": "code", "execution_count": 49, - "id": "22ebf158", + "id": "1b73833f", "metadata": {}, "outputs": [ { @@ -7916,7 +7916,7 @@ { "cell_type": "code", "execution_count": 50, - "id": "97a3bce1", + "id": "cfc2c7e9", "metadata": {}, "outputs": [ { @@ -8893,7 +8893,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4590561f", + "id": "15fe8cab", "metadata": {}, "outputs": [], "source": [] @@ -8901,7 +8901,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -8915,7 +8915,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.2" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/development/blah.png b/development/blah.png new file mode 100755 index 0000000..16d0841 Binary files /dev/null and b/development/blah.png differ diff --git a/development/blah2.png b/development/blah2.png new file mode 100755 index 0000000..a2b7f0b Binary files /dev/null and b/development/blah2.png differ diff --git a/development/delta_kernal.ipynb b/development/delta_kernal.ipynb index 1f68f04..41d1369 100755 --- a/development/delta_kernal.ipynb +++ b/development/delta_kernal.ipynb @@ -3,7 +3,7 @@ { "cell_type": "code", "execution_count": 1, - "id": "2548dfde", + "id": "according-advocate", "metadata": {}, "outputs": [], "source": [ @@ -40,7 +40,7 @@ { "cell_type": "code", "execution_count": 6, - "id": "77a9fa75", + "id": "twenty-commodity", "metadata": { "scrolled": false }, @@ -4876,7 +4876,7 @@ { "cell_type": "code", "execution_count": 9, - "id": "0c283ab1", + "id": "continent-hebrew", "metadata": {}, "outputs": [], "source": [ @@ -4908,7 +4908,7 @@ { "cell_type": "code", "execution_count": 124, - "id": "1a1b1247", + "id": "fe42940b", "metadata": {}, "outputs": [], "source": [ @@ -4918,7 +4918,7 @@ { "cell_type": "code", "execution_count": 44, - "id": "63e28f5f", + "id": "loving-roulette", "metadata": {}, "outputs": [], "source": [ @@ -4929,7 +4929,7 @@ { "cell_type": "code", "execution_count": 45, - "id": "adcb2dd4", + "id": "45430032", "metadata": {}, "outputs": [ { @@ -5905,7 +5905,7 @@ { "cell_type": "code", "execution_count": 46, - "id": "246b07dd", + "id": "21ce83c6", "metadata": {}, "outputs": [], "source": [ @@ -5915,7 +5915,7 @@ { "cell_type": "code", "execution_count": 51, - "id": "b6da0287", + "id": "53b601f2", "metadata": {}, "outputs": [ { @@ -7850,7 +7850,7 @@ { "cell_type": "code", "execution_count": 24, - "id": "181844d3", + "id": "aboriginal-adoption", "metadata": {}, "outputs": [], "source": [ @@ -7863,7 +7863,7 @@ { "cell_type": "code", "execution_count": 64, - "id": "1681023e", + "id": "wireless-power", "metadata": { "collapsed": true }, @@ -7952,7 +7952,7 @@ { "cell_type": "code", "execution_count": 125, - "id": "13ab7049", + "id": "double-starter", "metadata": {}, "outputs": [ { @@ -7975,7 +7975,7 @@ { "cell_type": "code", "execution_count": 126, - "id": "94cdb0c7", + "id": "aware-oklahoma", "metadata": {}, "outputs": [], "source": [ @@ -7985,7 +7985,7 @@ { "cell_type": "code", "execution_count": 128, - "id": "fba45a73", + "id": "8283f568", "metadata": {}, "outputs": [ { @@ -8962,7 +8962,7 @@ { "cell_type": "code", "execution_count": 129, - "id": "de0f0276", + "id": "09f24e51", "metadata": {}, "outputs": [], "source": [ @@ -8972,7 +8972,7 @@ { "cell_type": "code", "execution_count": 130, - "id": "8914e16e", + "id": "scheduled-council", "metadata": {}, "outputs": [ { @@ -9951,7 +9951,7 @@ { "cell_type": "code", "execution_count": 131, - "id": "3a2f9ee6", + "id": "d5f39efd", "metadata": {}, "outputs": [], "source": [ @@ -9962,7 +9962,7 @@ { "cell_type": "code", "execution_count": 132, - "id": "b1c6f483", + "id": "cf77fd24", "metadata": {}, "outputs": [ { @@ -10941,7 +10941,7 @@ { "cell_type": "code", "execution_count": 302, - "id": "08de92b9", + "id": "saving-attraction", "metadata": {}, "outputs": [], "source": [ @@ -10952,7 +10952,7 @@ { "cell_type": "code", "execution_count": 336, - "id": "f2ace21b", + "id": "important-constitution", "metadata": {}, "outputs": [ { @@ -10974,7 +10974,7 @@ { "cell_type": "code", "execution_count": 339, - "id": "418aa66e", + "id": "progressive-nevada", "metadata": { "scrolled": false }, @@ -11958,7 +11958,7 @@ { "cell_type": "code", "execution_count": 329, - "id": "faed8905", + "id": "later-lodge", "metadata": {}, "outputs": [ { @@ -12940,7 +12940,7 @@ { "cell_type": "code", "execution_count": 266, - "id": "c702f8e9", + "id": "covered-public", "metadata": {}, "outputs": [], "source": [ @@ -12958,7 +12958,7 @@ { "cell_type": "code", "execution_count": 267, - "id": "1e756eaa", + "id": "billion-exhibit", "metadata": {}, "outputs": [ { @@ -13012,7 +13012,7 @@ { "cell_type": "code", "execution_count": 12, - "id": "3633bcf4", + "id": "transsexual-industry", "metadata": {}, "outputs": [], "source": [ @@ -13022,7 +13022,7 @@ { "cell_type": "code", "execution_count": 268, - "id": "7e1121e6", + "id": "excited-rhythm", "metadata": {}, "outputs": [], "source": [ @@ -13033,7 +13033,7 @@ { "cell_type": "code", "execution_count": 269, - "id": "e17bb41e", + "id": "center-sherman", "metadata": {}, "outputs": [ { @@ -13054,7 +13054,7 @@ { "cell_type": "code", "execution_count": 270, - "id": "018edde9", + "id": "swiss-acceptance", "metadata": {}, "outputs": [ { @@ -14031,7 +14031,7 @@ { "cell_type": "code", "execution_count": 271, - "id": "eb70affc", + "id": "located-steal", "metadata": {}, "outputs": [ { @@ -14052,7 +14052,7 @@ { "cell_type": "code", "execution_count": 272, - "id": "000aac8f", + "id": "foreign-kitty", "metadata": {}, "outputs": [ { @@ -14073,7 +14073,7 @@ { "cell_type": "code", "execution_count": 275, - "id": "2efc477e", + "id": "fifth-balloon", "metadata": {}, "outputs": [ { @@ -15055,7 +15055,7 @@ { "cell_type": "code", "execution_count": 134, - "id": "ae73b9e0", + "id": "liked-clearing", "metadata": {}, "outputs": [], "source": [ @@ -15068,7 +15068,7 @@ { "cell_type": "code", "execution_count": 151, - "id": "6c4229c2", + "id": "primary-scroll", "metadata": {}, "outputs": [ { @@ -16055,7 +16055,7 @@ { "cell_type": "code", "execution_count": 144, - "id": "217272d4", + "id": "ecological-association", "metadata": {}, "outputs": [ { @@ -16082,7 +16082,7 @@ { "cell_type": "code", "execution_count": 152, - "id": "c22aebc3", + "id": "acoustic-maryland", "metadata": {}, "outputs": [ { @@ -16103,7 +16103,7 @@ { "cell_type": "code", "execution_count": 141, - "id": "8c867ce6", + "id": "unexpected-toilet", "metadata": {}, "outputs": [ { @@ -16146,7 +16146,7 @@ { "cell_type": "code", "execution_count": 140, - "id": "3339848e", + "id": "welcome-guinea", "metadata": {}, "outputs": [], "source": [ @@ -16156,7 +16156,7 @@ { "cell_type": "code", "execution_count": 17, - "id": "33531ebf", + "id": "f707e4ca", "metadata": {}, "outputs": [], "source": [ @@ -16167,7 +16167,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b4054ece", + "id": "28d26080", "metadata": {}, "outputs": [], "source": [ @@ -16177,7 +16177,7 @@ { "cell_type": "code", "execution_count": 18, - "id": "2ade332e", + "id": "novel-scroll", "metadata": {}, "outputs": [ { @@ -18110,7 +18110,7 @@ { "cell_type": "code", "execution_count": 22, - "id": "fa6e2701", + "id": "c7c9ff9d", "metadata": {}, "outputs": [ { @@ -19086,7 +19086,7 @@ { "cell_type": "code", "execution_count": 25, - "id": "ed34d057", + "id": "ea15bcd3", "metadata": {}, "outputs": [ { @@ -20028,7 +20028,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8f6a5363", + "id": "90255bca", "metadata": {}, "outputs": [], "source": [] @@ -20050,7 +20050,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.2" + "version": "3.9.15" }, "vscode": { "interpreter": { diff --git a/development/diag_brightness.py b/development/diag_brightness.py deleted file mode 100644 index 2ef084f..0000000 --- a/development/diag_brightness.py +++ /dev/null @@ -1,86 +0,0 @@ -import numpy as np -import matplotlib -matplotlib.use('Agg') -import matplotlib.pyplot as plt - -data = np.load('/Users/rri38/Documents/work/code/tess/tessreduce/development/test_bkg.npy') -time = np.load('/Users/rri38/Documents/work/code/tess/tessreduce/development/test_bkg_time.npy') - -# Use central pixel for the time series panels (same as run_diag) -px, py = 100, 100 -series = data[:, px, py] -T = len(series) - -flat = data.ravel() -flat = flat[np.isfinite(flat)] - -# --- Percentile thresholds at several candidate values --- -pcts = [50, 60, 70, 80, 90] -pct_thresholds = {p: np.nanpercentile(flat, p) for p in pcts} - -# --- Sigma-clipped stats --- -clipped = flat.copy() -for _ in range(5): - med = np.median(clipped) - std = np.std(clipped) - if std == 0: - break - clipped = clipped[np.abs(clipped - med) < 2.0 * std] -clip_mean = float(np.mean(clipped)) -clip_std = float(np.std(clipped)) -sigma_threshold = clip_mean + 2.0 * clip_std - -print(f"Flat pixel count: {len(flat):,}") -print(f"Sigma-clip: mean={clip_mean:.4f}, std={clip_std:.4f}, threshold={sigma_threshold:.4f}") -for p, t in pct_thresholds.items(): - frac_above = np.mean(flat > t) - print(f" pct={p}: threshold={t:.4f}, frac_above={frac_above:.3f}") -frac_above_sigma = np.mean(flat > sigma_threshold) -print(f" sigma-clip (mean+2σ): threshold={sigma_threshold:.4f}, frac_above={frac_above_sigma:.3f}") - -# ── Figure: 3 panels ────────────────────────────────────────────────────────── -fig, axes = plt.subplots(3, 1, figsize=(14, 12)) -fig.suptitle('Brightness threshold diagnostics — pixel (100,100)', fontsize=12) - -# Panel 1: histogram of all pixel values + threshold lines -ax = axes[0] -counts, bin_edges = np.histogram(flat, bins=300) -bin_centres = 0.5 * (bin_edges[:-1] + bin_edges[1:]) -ax.semilogy(bin_centres, counts, color='steelblue', lw=0.8, label='All pixels') -colors = plt.cm.Reds(np.linspace(0.3, 0.9, len(pcts))) -for (p, t), c in zip(pct_thresholds.items(), colors): - ax.axvline(t, color=c, lw=1.0, ls='--', label=f'pct={p} ({t:.3f})') -ax.axvline(sigma_threshold, color='black', lw=1.5, ls='-', label=f'mean+2σ clipped ({sigma_threshold:.3f})') -ax.set_xlabel('Pixel value') -ax.set_ylabel('Count (log)') -ax.set_title('Global pixel value distribution with candidate thresholds') -ax.legend(fontsize=8, ncol=2) - -# Panel 2: per-frame mean brightness + threshold lines -frame_mean = data.mean(axis=(1, 2)) -ax = axes[1] -ax.plot(time, frame_mean, lw=0.7, color='steelblue', label='Per-frame mean brightness') -for (p, t), c in zip(pct_thresholds.items(), colors): - ax.axhline(t, color=c, lw=0.8, ls='--') -ax.axhline(sigma_threshold, color='black', lw=1.5, ls='-', label='mean+2σ clipped') -ax.set_xlabel('Time (BTJD)') -ax.set_ylabel('Mean flux') -ax.set_title('Per-frame mean brightness vs time') -ax.legend(fontsize=8) - -# Panel 3: bright mask fraction over time for each threshold -ax = axes[2] -for (p, t), c in zip(pct_thresholds.items(), colors): - mask_frac = (data > t).mean(axis=(1, 2)) - ax.plot(time, mask_frac, color=c, lw=0.8, label=f'pct={p}') -mask_frac_sigma = (data > sigma_threshold).mean(axis=(1, 2)) -ax.plot(time, mask_frac_sigma, color='black', lw=1.5, label='mean+2σ clipped') -ax.set_xlabel('Time (BTJD)') -ax.set_ylabel('Fraction of pixels above threshold') -ax.set_title('Bright-mask active fraction over time (per frame)') -ax.legend(fontsize=8) - -plt.tight_layout() -plt.savefig('/Users/rri38/Documents/work/code/tess/tessreduce/development/diag_brightness.png', dpi=120) -plt.close() -print("Saved diag_brightness.png") diff --git a/development/diag_full_cube.py b/development/diag_full_cube.py deleted file mode 100644 index df8b456..0000000 --- a/development/diag_full_cube.py +++ /dev/null @@ -1,120 +0,0 @@ -import numpy as np -import matplotlib -matplotlib.use('Agg') -import matplotlib.pyplot as plt -import pandas as pd -import time as time_mod -import sys -sys.path.insert(0, '/Users/rri38/Documents/work/code/tess/tessreduce/development') -from run_diag import adaptive_medfilt_3d, _get_segments - -_dev = '/Users/rri38/Documents/work/code/tess/tessreduce/development/' -_base = "https://heasarc.gsfc.nasa.gov/docs/tess/data/TESSVectors/Vectors/FFI_Cadence/" - -data = np.load(f'{_dev}test_bkg2.npy') -time = np.load(f'{_dev}test_bkg2_time.npy') -print(f"Data shape: {data.shape}") - -_df = pd.read_csv(f"{_base}TessVectors_S034_C1_FFI.csv", comment='#') -earth_angle = np.interp(time - 57000, _df['MidTime'].values, _df['Earth_Camera_Angle'].values) -moon_angle = np.interp(time - 57000, _df['MidTime'].values, _df['Moon_Camera_Angle'].values) - -t0 = time_mod.time() -smoothed, windows, variability, _ = adaptive_medfilt_3d( - data, - time=time, - metric='deviation', - coarse_windows=(11, 21, 51, 101), - low_pct=5, - high_pct=80, - local_norm_window=201, - w_min=3, - w_max=51, - n_jobs=-1, - window_smooth_size=1, - earth_angle=earth_angle, - moon_angle=moon_angle, - scatter_angle_thresh=50.0, -) -elapsed = time_mod.time() - t0 -print(f"Done in {elapsed:.1f}s") - -residual = data - smoothed -mean_res = np.nanmean(np.abs(residual)) -print(f"Full cube residual: mean={mean_res:.5f}, std={np.nanstd(residual):.5f}") -print(f"Window: mean={windows.mean():.1f}, std={windows.std():.1f}, frac_wmax={np.mean(windows==51):.3f}") - -segs = _get_segments(time, gap_thresh=3.0) - -# ── Figure 1: representative pixel (20,20) ───────────────────────────────── -px, py = 20, 20 -raw1d = data[:, px, py] -sm1d = smoothed[:, px, py] -win1d = windows[:, px, py] -res1d = raw1d - sm1d - -def with_breaks(t, y, segments): - t_out, y_out = [], [] - for s, e in segments: - t_out.extend(t[s:e].tolist()) - y_out.extend(y[s:e].tolist()) - t_out.append(np.nan) - y_out.append(np.nan) - return np.array(t_out), np.array(y_out) - -t_raw, raw_r = with_breaks(time, raw1d, segs) -t_sm, sm_r = with_breaks(time, sm1d, segs) -t_w, win_r = with_breaks(time, win1d.astype(float), segs) -t_r, res_r = with_breaks(time, res1d, segs) - -fig, axes = plt.subplots(4, 1, figsize=(16, 14), sharex=True) -fig.suptitle('Full cube run — test_bkg2, pixel (20,20) [w_max=51, scatter_angle_thresh=50]', fontsize=11) - -ax = axes[0] -ax.plot(t_raw, raw_r, lw=0.6, color='steelblue', alpha=0.7, label='Raw') -ax.plot(t_sm, sm_r, lw=1.2, color='firebrick', label='Smoothed') -ax.set_ylabel('Flux'); ax.set_title('Raw + smoothed'); ax.legend(fontsize=8) - -ax = axes[1] -ax.plot(t_r, res_r, lw=0.7, color='darkgreen', label='Residual (raw − smooth)') -ax.axhline(0, color='k', lw=0.5, ls='--') -ax.set_ylabel('Residual'); ax.set_title('Residual'); ax.legend(fontsize=8) - -ax = axes[2] -ax.plot(t_r, np.abs(res_r), lw=0.7, color='purple', label='|Residual|') -ax.set_ylabel('|Residual|'); ax.set_title('Absolute residual'); ax.legend(fontsize=8) - -ax = axes[3] -ax.plot(t_w, win_r, lw=0.8, color='darkorange', label='Window size') -ax.set_ylabel('Window size'); ax.set_xlabel('Time (BTJD)') -ax.set_title('Adaptive window size'); ax.legend(fontsize=8) - -plt.tight_layout() -plt.savefig(f'{_dev}residual_fullcube_test_bkg2_px.png', dpi=120) -plt.close() -print("Saved residual_fullcube_test_bkg2_px.png") - -# ── Figure 2: mean residual image and window image ───────────────────────── -fig, axes = plt.subplots(1, 3, figsize=(16, 5)) -fig.suptitle('Full cube — test_bkg2 spatial summary', fontsize=12) - -mean_abs_res = np.nanmean(np.abs(residual), axis=0) -mean_win = windows.mean(axis=0) -mean_var = variability.mean(axis=0) - -im0 = axes[0].imshow(mean_abs_res, origin='lower', cmap='inferno') -axes[0].set_title('Mean |residual| per pixel') -plt.colorbar(im0, ax=axes[0]) - -im1 = axes[1].imshow(mean_win, origin='lower', cmap='viridis', vmin=3, vmax=51) -axes[1].set_title('Mean window size per pixel') -plt.colorbar(im1, ax=axes[1]) - -im2 = axes[2].imshow(mean_var, origin='lower', cmap='plasma') -axes[2].set_title('Mean variability metric per pixel') -plt.colorbar(im2, ax=axes[2]) - -plt.tight_layout() -plt.savefig(f'{_dev}residual_fullcube_test_bkg2_spatial.png', dpi=120) -plt.close() -print("Saved residual_fullcube_test_bkg2_spatial.png") diff --git a/development/diag_grb_pixels.py b/development/diag_grb_pixels.py deleted file mode 100644 index de4e66d..0000000 --- a/development/diag_grb_pixels.py +++ /dev/null @@ -1,93 +0,0 @@ -import numpy as np -import matplotlib -matplotlib.use('Agg') -import matplotlib.pyplot as plt -import pandas as pd -import sys -sys.path.insert(0, '/Users/rri38/Documents/work/code/tess/tessreduce/development') -from run_diag import adaptive_medfilt_3d, _get_segments - -_dev = '/Users/rri38/Documents/work/code/tess/tessreduce/development/' -_base = "https://heasarc.gsfc.nasa.gov/docs/tess/data/TESSVectors/Vectors/FFI_Cadence/" - -data = np.load(f'{_dev}test_bkg2.npy') -time = np.load(f'{_dev}test_bkg2_time.npy') -T = len(time) - -_df = pd.read_csv(f"{_base}TessVectors_S034_C1_FFI.csv", comment='#') -earth_angle = np.interp(time - 57000, _df['MidTime'].values, _df['Earth_Camera_Angle'].values) -moon_angle = np.interp(time - 57000, _df['MidTime'].values, _df['Moon_Camera_Angle'].values) - -# Central 3×3 pixels around (25,25) -cx, cy = 25, 25 -pixels = [(cx+dx, cy+dy) for dx in (-1, 0, 1) for dy in (-1, 0, 1)] - -segs = _get_segments(time, gap_thresh=3.0) - -def with_breaks(t, y, segments): - t_out, y_out = [], [] - for s, e in segments: - t_out.extend(t[s:e].tolist()) - y_out.extend(y[s:e].tolist()) - t_out.append(np.nan) - y_out.append(np.nan) - return np.array(t_out), np.array(y_out) - -fig, axes = plt.subplots(9, 3, figsize=(20, 30)) -fig.suptitle('GRB central 3×3 pixels — test_bkg2 [w_max=51, scatter_angle_thresh=50]', fontsize=13) - -for idx, (px, py) in enumerate(pixels): - cube = data[:, px:px+1, py:py+1] - raw = cube[:, 0, 0] - - sm, win, _, _ = adaptive_medfilt_3d( - cube, time=time, metric='deviation', - coarse_windows=(11, 21, 51, 101), - low_pct=5, high_pct=80, - local_norm_window=201, - w_min=3, w_max=51, n_jobs=1, - window_smooth_size=1, - earth_angle=earth_angle, - moon_angle=moon_angle, - scatter_angle_thresh=50.0, - ) - sm1d = sm[:, 0, 0] - win1d = win[:, 0, 0] - res1d = raw - sm1d - - t_raw, raw_r = with_breaks(time, raw, segs) - t_sm, sm_r = with_breaks(time, sm1d, segs) - t_w, win_r = with_breaks(time, win1d.astype(float), segs) - t_r, res_r = with_breaks(time, res1d, segs) - - row = idx - ax0 = axes[row, 0] - ax0.plot(t_raw, raw_r, lw=0.5, color='steelblue', alpha=0.6, label='Raw') - ax0.plot(t_sm, sm_r, lw=1.0, color='firebrick', label='Smoothed') - ax0.set_ylabel('Flux', fontsize=7) - ax0.set_title(f'Pixel ({px},{py}) — raw + smoothed', fontsize=8) - ax0.legend(fontsize=6) - ax0.tick_params(labelsize=6) - - ax1 = axes[row, 1] - ax1.plot(t_r, res_r, lw=0.5, color='darkgreen') - ax1.axhline(0, color='k', lw=0.4, ls='--') - ax1.set_ylabel('Residual', fontsize=7) - ax1.set_title(f'Residual (mean|res|={np.nanmean(np.abs(res1d)):.4f})', fontsize=8) - ax1.tick_params(labelsize=6) - - ax2 = axes[row, 2] - ax2.plot(t_w, win_r, lw=0.6, color='darkorange') - ax2.set_ylabel('Window', fontsize=7) - ax2.set_title(f'Window size (mean={win1d.mean():.1f})', fontsize=8) - ax2.tick_params(labelsize=6) - - print(f" ({px},{py}): res={np.nanmean(np.abs(res1d)):.5f}, win_mean={win1d.mean():.1f}") - -for ax in axes[-1]: - ax.set_xlabel('Time (MJD)', fontsize=7) - -plt.tight_layout() -plt.savefig(f'{_dev}diag_grb_central_pixels.png', dpi=100) -plt.close() -print("Saved diag_grb_central_pixels.png") diff --git a/development/diag_residual.py b/development/diag_residual.py deleted file mode 100644 index 9403e0f..0000000 --- a/development/diag_residual.py +++ /dev/null @@ -1,110 +0,0 @@ -import numpy as np -import matplotlib -matplotlib.use('Agg') -import matplotlib.pyplot as plt -import pandas as pd -import sys -sys.path.insert(0, '/Users/rri38/Documents/work/code/tess/tessreduce/development') -from run_diag import adaptive_medfilt_3d, _get_segments, _make_odd - -_base = "https://heasarc.gsfc.nasa.gov/docs/tess/data/TESSVectors/Vectors/FFI_Cadence/" -_dev = '/Users/rri38/Documents/work/code/tess/tessreduce/development/' - -datasets = [ - dict(ds='test_bkg', px=100, py=100, sector=38, cam=4, label='pixel (100,100)'), - dict(ds='test_bkg2', px=20, py=20, sector=34, cam=1, label='pixel (20,20)'), -] - - -def with_breaks(t, y, segments): - t_out, y_out = [], [] - for s, e in segments: - t_out.extend(t[s:e].tolist()) - y_out.extend(y[s:e].tolist()) - t_out.append(np.nan) - y_out.append(np.nan) - return np.array(t_out), np.array(y_out) - - -for cfg in datasets: - ds = cfg['ds'] - px, py = cfg['px'], cfg['py'] - label = cfg['label'] - - data = np.load(f"{_dev}{ds}.npy") - time = np.load(f"{_dev}{ds}_time.npy") - cube = data[:, px:px+1, py:py+1] - raw = cube[:, 0, 0] - - segs = _get_segments(time, gap_thresh=3.0) - - _df = pd.read_csv(f"{_base}TessVectors_S0{cfg['sector']:02d}_C{cfg['cam']}_FFI.csv", comment='#') - earth_angle = np.interp(time - 57000, _df['MidTime'].values, _df['Earth_Camera_Angle'].values) - moon_angle = np.interp(time - 57000, _df['MidTime'].values, _df['Moon_Camera_Angle'].values) - - smoothed, windows, variability, _ = adaptive_medfilt_3d( - cube, - time=time, - metric='deviation', - coarse_windows=(11, 21, 51, 101), - low_pct=5, - high_pct=80, - local_norm_window=201, - w_min=3, - w_max=51, - n_jobs=1, - window_smooth_size=1, - earth_angle=earth_angle, - moon_angle=moon_angle, - scatter_angle_thresh=50.0, - ) - - sm = smoothed[:, 0, 0] - win = windows[:, 0, 0] - residual = raw - sm - - t_r, res_r = with_breaks(time, residual, segs) - t_s, sm_r = with_breaks(time, sm, segs) - t_w, win_r = with_breaks(time, win.astype(float), segs) - t_raw, raw_r = with_breaks(time, raw, segs) - - mean_res = np.nanmean(np.abs(residual)) - print(f"{ds}: residual mean={mean_res:.5f}, std={np.nanstd(residual):.5f}, " - f"max abs={np.nanmax(np.abs(residual)):.5f}, win_mean={win.mean():.1f}, " - f"frac_wmax={np.mean(win==101):.3f}") - - fig, axes = plt.subplots(4, 1, figsize=(16, 14), sharex=True) - fig.suptitle(f'Residual diagnostics — {label} [w_max=51, scatter_angle_thresh=50]', fontsize=12) - - ax = axes[0] - ax.plot(t_raw, raw_r, lw=0.6, color='steelblue', alpha=0.7, label='Raw') - ax.plot(t_s, sm_r, lw=1.2, color='firebrick', label='Smoothed') - ax.set_ylabel('Flux') - ax.set_title('Raw + smoothed') - ax.legend(fontsize=8) - - ax = axes[1] - ax.plot(t_r, res_r, lw=0.7, color='darkgreen', label='Residual (raw − smooth)') - ax.axhline(0, color='k', lw=0.5, ls='--') - ax.set_ylabel('Residual') - ax.set_title('Residual') - ax.legend(fontsize=8) - - ax = axes[2] - ax.plot(t_r, np.abs(res_r), lw=0.7, color='purple', label='|Residual|') - ax.set_ylabel('|Residual|') - ax.set_title('Absolute residual') - ax.legend(fontsize=8) - - ax = axes[3] - ax.plot(t_w, win_r, lw=0.8, color='darkorange', label='Window size') - ax.set_ylabel('Window size') - ax.set_xlabel('Time (BTJD)') - ax.set_title('Adaptive window size') - ax.legend(fontsize=8) - - plt.tight_layout() - outfile = f"{_dev}residual_plot_{ds}.png" - plt.savefig(outfile, dpi=120) - plt.close() - print(f"Saved {outfile}") diff --git a/development/fub.png b/development/fub.png new file mode 100755 index 0000000..bbe3fcb Binary files /dev/null and b/development/fub.png differ diff --git a/development/fub_SLR.pdf b/development/fub_SLR.pdf new file mode 100755 index 0000000..0d391a9 Binary files /dev/null and b/development/fub_SLR.pdf differ diff --git a/development/fub_cal.png b/development/fub_cal.png new file mode 100755 index 0000000..c0b3b25 Binary files /dev/null and b/development/fub_cal.png differ diff --git a/development/fub_diff_diag.pdf b/development/fub_diff_diag.pdf new file mode 100755 index 0000000..2049d75 Binary files /dev/null and b/development/fub_diff_diag.pdf differ diff --git a/development/fub_disp.pdf b/development/fub_disp.pdf new file mode 100755 index 0000000..8350fe9 Binary files /dev/null and b/development/fub_disp.pdf differ diff --git a/development/fubcal_sources.pdf b/development/fubcal_sources.pdf new file mode 100755 index 0000000..d55264f Binary files /dev/null and b/development/fubcal_sources.pdf differ diff --git a/development/fubcal_zp.pdf b/development/fubcal_zp.pdf new file mode 100755 index 0000000..39952e7 Binary files /dev/null and b/development/fubcal_zp.pdf differ diff --git a/development/ground_test.png b/development/ground_test.png new file mode 100755 index 0000000..19de5e1 Binary files /dev/null and b/development/ground_test.png differ diff --git a/development/improving_psf_photometry.ipynb b/development/improving_psf_photometry.ipynb index 0af6619..570d85e 100644 --- a/development/improving_psf_photometry.ipynb +++ b/development/improving_psf_photometry.ipynb @@ -3,7 +3,7 @@ { "cell_type": "code", "execution_count": 1, - "id": "260e546b", + "id": "8cd36b0d", "metadata": {}, "outputs": [], "source": [ @@ -15,9400 +15,25 @@ }, { "cell_type": "code", - "execution_count": 3, - "id": "ba3fa7b8", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "| Sector | Camera | CCD | Covers | Time difference |\n", - "| | | | | (days) |\n", - "|----------+----------+-------+----------+--------------------|\n", - "| 5 | 3 | 1 | False | -727 |\n", - "| 6 | 3 | 2 | False | -700 |\n", - "| 32 | 3 | 1 | True | 0 |\n", - "| 33 | 3 | 2 | False | 10 |\n" - ] - } - ], - "source": [ - "obs = tr.spacetime_lookup(ra=82.4684167,dec=-37.0453889,time=59190)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "075a617c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "| Sector | Covers | Time difference |\n", - "| | | (days) |\n", - "|----------+----------+--------------------|\n", - "| 1 | False | -792 |\n", - "| 2 | False | -763 |\n", - "| 3 | False | -735 |\n", - "| 4 | False | -707 |\n", - "| 5 | False | -681 |\n", - "| 6 | False | -654 |\n", - "| 7 | False | -628 |\n", - "| 8 | False | -602 |\n", - "| 9 | False | -576 |\n", - "| 10 | False | -549 |\n", - "| 11 | False | -520 |\n", - "| 12 | False | -491 |\n", - "| 13 | False | -462 |\n", - "| 27 | False | -84 |\n", - "| 28 | False | -57 |\n", - "| 30 | False | -1 |\n", - "| 31 | True | 0 |\n", - "| 32 | False | 28 |\n", - "| 33 | False | 56 |\n", - "| 34 | False | 83 |\n", - "| 35 | False | 110 |\n", - "| 36 | False | 136 |\n", - "| 37 | False | 162 |\n", - "| 38 | False | 188 |\n", - "| 39 | False | 216 |\n", - "| 61 | False | 818 |\n", - "| 62 | False | 843 |\n", - "| 63 | False | 869 |\n", - "| 64 | False | 896 |\n", - "| 65 | False | 924 |\n", - "| 67 | False | 982 |\n", - "| 68 | False | 1010 |\n", - "| 69 | False | 1037 |\n" - ] - } - ], - "source": [ - "obs = tr.sn_lookup('sn2020xyw')" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "cf8d05b4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "getting TPF from TESScut\n", - "made reference\n", - "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", - "made source mask\n", - "calculating background\n", - "background subtracted\n", - "aligning images\n", - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess = tr.tessreduce(obs_list=obs,calibrate=False,size=40,corr_correction=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "69baaf0a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0.58443569 0.44100115]\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "lc,s = tess.diff_lc(x=20,y=19,phot_method='psf',plot=True,bkg_poly_order=3);" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "f55aff41", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(lc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "34971e9e", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.shift[:,1])\n", - "plt.plot(tess.shift[:,0])" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "d9560d41", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[2800],vmin=-5,vmax=5)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "a61da9e7", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "av = np.nanmedian(lc[1,1698:2000])\n", - "plt.figure()\n", - "plt.plot(lc[0],lc[1]- av)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "eb429dec", - "metadata": {}, - "outputs": [], - "source": [ - "#lc[1] = lc[1] -av\n", - "tess.lc = lc\n", - "m = tess.to_mag(zp=20.44)" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "448fef84", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Calculating field star zeropoint\n", - "target is below -30 dec, calibrating to SkyMapper photometry.\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess.plotter(ground=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "b13d4627", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "20.338493667102938" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.tzp" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "id": "0becb16d", - "metadata": {}, - "outputs": [], - "source": [ - "l = tess.bin_data(time_bin=3/24)" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "id": "d9cffd20", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "(59186.0, 59200.0)" - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(lc[0],-2.5*np.log10(lc[1]) + 16.4,'.',alpha=0.5,label='10 min')\n", - "plt.plot(l[0],-2.5*np.log10(l[1]) + 16.4,'.',label='3 hour')\n", - "plt.gca().invert_yaxis()\n", - "plt.ylabel('mag')\n", - "plt.xlabel('MJD')\n", - "plt.legend()\n", - "plt.ylim(22,15.9)\n", - "plt.xlim(59186,59200)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "4c156365", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", - "made source mask\n", - "calculating background\n", - "background subtracted\n", - "aligning images\n", - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess = tr.tessreduce(tpf='../../SN_individual/2019vxm/s18.fits',calibrate=False,corr_correction=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "00232b24", + "execution_count": 2, + "id": "facb8494", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[0.41095348 0.4118731 ]\n" + "made reference\n", + "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", + "made source mask\n", + "calculating background\n", + "background subtracted\n", + "aligning images\n", + "!!Re-running for difference image!!\n", + "shifting images\n", + "remade mask\n", + "background\n", + "background correlation correction\n" ] }, { @@ -10408,7 +1033,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -10419,13 +1044,13 @@ } ], "source": [ - "lc,s = tess.diff_lc(phot_method='psf',plot=True);" + "tess = tr.tessreduce(tpf='../../SN_individual/2019vxm/s18.fits',calibrate=False)" ] }, { "cell_type": "code", - "execution_count": 37, - "id": "6f3f3324", + "execution_count": 3, + "id": "0d2dba92", "metadata": {}, "outputs": [ { @@ -11425,7 +2050,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -11442,7 +2067,7 @@ { "cell_type": "code", "execution_count": 5, - "id": "63eae272", + "id": "182310d8", "metadata": {}, "outputs": [ { @@ -11474,8 +2099,8 @@ }, { "cell_type": "code", - "execution_count": 35, - "id": "9dab3e53", + "execution_count": 2, + "id": "e54b7c1b", "metadata": {}, "outputs": [ { @@ -11485,19 +2110,42 @@ "| Sector | Covers | Time difference |\n", "| | | (days) |\n", "|----------+----------+--------------------|\n", - "| 27 | False | -135.218 |\n", - "| 67 | False | 930.782 |\n" + "| 14 | False | -108 |\n", + "| 15 | False | -81 |\n", + "| 16 | False | -55 |\n", + "| 17 | False | -29 |\n", + "| 18 | False | -4 |\n", + "| 21 | False | 51 |\n", + "| 24 | False | 137 |\n", + "| 41 | False | 600 |\n", + "| 47 | False | 760 |\n", + "| 48 | False | 789 |\n", + "| 51 | False | 873 |\n", + "| 54 | False | 951 |\n", + "| 55 | False | 978 |\n", + "| 56 | False | 1005 |\n", + "| 57 | False | 1034 |\n", + "| 58 | False | 1063 |\n", + "| 60 | False | 1118 |\n", + "| 74 | False | 1494 |\n", + "| 75 | False | 1521 |\n", + "| 76 | False | 1548 |\n", + "| 77 | False | 1577 |\n", + "| 78 | False | 1605 |\n", + "| 81 | False | 1688 |\n", + "| 82 | False | 1714 |\n", + "| 83 | False | 1740 |\n" ] } ], "source": [ - "obs = tr.sn_lookup('sn2020aclz')" + "obs = tr.sn_lookup('sn2019vxm')" ] }, { "cell_type": "code", "execution_count": 3, - "id": "3458f627", + "id": "cc3fec05", "metadata": {}, "outputs": [ { @@ -12532,7 +3180,7 @@ { "cell_type": "code", "execution_count": 4, - "id": "ba2c85b4", + "id": "22d27130", "metadata": {}, "outputs": [ { @@ -13548,8 +4196,8 @@ }, { "cell_type": "code", - "execution_count": 42, - "id": "3b8d6fc6", + "execution_count": 6, + "id": "81e18c0e", "metadata": {}, "outputs": [ { @@ -14549,7 +5197,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -14561,27 +5209,25 @@ { "data": { "text/plain": [ - "" + "[]" ] }, - "execution_count": 42, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plt.figure()\n", - "plt.plot(tess.lc[0],tess.lc[1],'.',label='aperture')\n", - "plt.plot(lc[0],lc[1],'.',label='psf',ms=3)\n", - "\n", - "plt.fill_between(lc[0],lc[1]-lc[2],lc[1]+lc[2],color='C1',alpha=0.5)\n", - "plt.legend()\n" + "plt.plot(tess.lc[1])\n", + "plt.plot(lc[1])\n", + "#plt.fill_between(lc[0],lc[1]-lc[2],lc[1]+lc[2],color='C1',alpha=0.5)\n" ] }, { "cell_type": "code", "execution_count": 34, - "id": "45c55e41", + "id": "e0e7bf9f", "metadata": {}, "outputs": [ { @@ -15610,7 +6256,7 @@ { "cell_type": "code", "execution_count": 7, - "id": "fb797917", + "id": "f2ba2c02", "metadata": {}, "outputs": [], "source": [ @@ -15621,7 +6267,7 @@ { "cell_type": "code", "execution_count": 8, - "id": "77266bcb", + "id": "46719f3f", "metadata": {}, "outputs": [ { @@ -16649,7 +7295,7 @@ { "cell_type": "code", "execution_count": 16, - "id": "40e901b6", + "id": "1de7f3fd", "metadata": {}, "outputs": [], "source": [ @@ -16911,7 +7557,7 @@ { "cell_type": "code", "execution_count": 442, - "id": "c1a220ab", + "id": "ef5861f6", "metadata": {}, "outputs": [], "source": [ @@ -16921,7 +7567,7 @@ { "cell_type": "code", "execution_count": 28, - "id": "4be17d0f", + "id": "085826fd", "metadata": {}, "outputs": [], "source": [ @@ -16931,7 +7577,7 @@ { "cell_type": "code", "execution_count": 29, - "id": "a7f679b2", + "id": "74e84cac", "metadata": {}, "outputs": [ { @@ -16952,7 +7598,7 @@ { "cell_type": "code", "execution_count": 48, - "id": "ebecad73", + "id": "45b1d341", "metadata": {}, "outputs": [ { @@ -63178,7 +53824,7 @@ { "cell_type": "code", "execution_count": 15, - "id": "9246ec6e", + "id": "28b259b6", "metadata": {}, "outputs": [ { @@ -63401,7 +54047,7 @@ { "cell_type": "code", "execution_count": 30, - "id": "e75ca0e5", + "id": "73ab9229", "metadata": {}, "outputs": [ { @@ -64429,7 +55075,7 @@ { "cell_type": "code", "execution_count": 22, - "id": "d87cc016", + "id": "e178a81a", "metadata": {}, "outputs": [ { @@ -64450,7 +55096,7 @@ { "cell_type": "code", "execution_count": 23, - "id": "aee837d2", + "id": "4dde4da2", "metadata": {}, "outputs": [ { @@ -64471,7 +55117,7 @@ { "cell_type": "code", "execution_count": 24, - "id": "fe2f5153", + "id": "d7054437", "metadata": {}, "outputs": [ { @@ -64492,7 +55138,7 @@ { "cell_type": "code", "execution_count": 31, - "id": "cc510f62", + "id": "e0d11fce", "metadata": {}, "outputs": [ { @@ -64512,7 +55158,7 @@ { "cell_type": "code", "execution_count": 32, - "id": "72b8106f", + "id": "2db06b62", "metadata": { "scrolled": false }, @@ -65549,7 +56195,7 @@ { "cell_type": "code", "execution_count": 452, - "id": "c41e9450", + "id": "64eb27e6", "metadata": {}, "outputs": [ { @@ -66577,7 +57223,7 @@ { "cell_type": "code", "execution_count": 437, - "id": "3371e0f4", + "id": "56465f61", "metadata": {}, "outputs": [], "source": [ @@ -66588,7 +57234,7 @@ { "cell_type": "code", "execution_count": 438, - "id": "dd799703", + "id": "66e97799", "metadata": {}, "outputs": [ { @@ -67616,7 +58262,7 @@ { "cell_type": "code", "execution_count": 440, - "id": "c54b139a", + "id": "1e8dbf27", "metadata": {}, "outputs": [ { @@ -67637,7 +58283,7 @@ { "cell_type": "code", "execution_count": 365, - "id": "40016dee", + "id": "13fd3a79", "metadata": { "scrolled": false }, @@ -68667,7 +59313,7 @@ { "cell_type": "code", "execution_count": 214, - "id": "27418e37", + "id": "2aa275e3", "metadata": {}, "outputs": [ { @@ -68686,7 +59332,7 @@ { "cell_type": "code", "execution_count": null, - "id": "89d3603a", + "id": "62469874", "metadata": {}, "outputs": [], "source": [] @@ -68694,7 +59340,7 @@ { "cell_type": "code", "execution_count": 29, - "id": "1a63182a", + "id": "aa90672f", "metadata": {}, "outputs": [ { @@ -68726,7 +59372,7 @@ { "cell_type": "code", "execution_count": 76, - "id": "244dddfc", + "id": "17b8d4ae", "metadata": {}, "outputs": [], "source": [ @@ -68743,7 +59389,7 @@ { "cell_type": "code", "execution_count": 77, - "id": "17cf6fd9", + "id": "8c64fe21", "metadata": {}, "outputs": [ { @@ -68770,7 +59416,7 @@ { "cell_type": "code", "execution_count": 46, - "id": "6b6fcba4", + "id": "12a96e00", "metadata": {}, "outputs": [ { @@ -68797,7 +59443,7 @@ { "cell_type": "code", "execution_count": 43, - "id": "aac353a7", + "id": "744a5b06", "metadata": {}, "outputs": [ { @@ -68824,7 +59470,7 @@ { "cell_type": "code", "execution_count": 61, - "id": "408aac31", + "id": "a2acba14", "metadata": {}, "outputs": [], "source": [ @@ -68834,7 +59480,7 @@ { "cell_type": "code", "execution_count": 63, - "id": "49def80b", + "id": "88dc024a", "metadata": {}, "outputs": [ { @@ -68852,1751 +59498,10 @@ "a[1:]" ] }, - { - "cell_type": "code", - "execution_count": 5, - "id": "d1ff011e", - "metadata": {}, - "outputs": [], - "source": [ - "from astropy.io import fits " - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "1380a625", - "metadata": {}, - "outputs": [], - "source": [ - "hdu = fits.open('/Users/rri38/Documents/work/code/cube_scene/dev/sat/ADP.2022-07-14T15:34:49.531.fits')" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "c23322ba", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "SIMPLE = T / file does conform to FITS standard \n", - "BITPIX = 8 / number of bits per data pixel \n", - "NAXIS = 0 / number of data axes \n", - "EXTEND = T / FITS dataset may contain extensions \n", - "COMMENT FITS (Flexible Image Transport System) format is defined in 'Astronomy\n", - "COMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H \n", - "DATE = '2022-07-14T15:32:30' / file creation date (YYYY-MM-DDThh:mm:ss UT) \n", - "ORIGIN = 'ESO-PARANAL' / European Southern Observatory \n", - "TELESCOP= 'ESO-VLT-U4' / ESO \n", - "INSTRUME= 'MUSE ' / Instrument used. \n", - "RA = 25.3852701713977 / [deg] Image center (J2000) \n", - "DEC = -54.4635284703773 / [deg] Image center (J2000) \n", - "EQUINOX = 2000. / Standard FK5 \n", - "EXPTIME = 2723.62004273548 / [s] Total integration time per pixel \n", - "MJD-OBS = 59754.36533661 / [d] Start of observations (days) \n", - "MJD-END = 59754.4009713696 / [d] End of observations (days) \n", - "DATE-OBS= '2022-06-24T08:46:05.082' / Observing date \n", - "UTC = 31553. / [s] 08:45:53.000 UTC \n", - "LST = 80053.396 / [s] 22:14:13.396 LST \n", - "PI-COI = 'UNKNOWN ' / PI-COI name. \n", - "OBSERVER= 'UNKNOWN ' / Name of observer. \n", - "OBJECT = 'J0141-5427' / Original target. \n", - "TEXPTIME= 2960. / [s] Total integration time of all exposures \n", - "NCOMBINE= 2 / No. of combined raw science data files \n", - "RADESYS = 'FK5 ' / Coordinate system \n", - "PIPEFILE= 'r.MUSE.2022-06-24T08:46:05.083_tpl_0000.fits' / no comment \n", - "SPECSYS = 'BARYCENT' / Spectral reference frame \n", - "ARCFILE = 'ADP.2022-07-14T15:34:49.531.fits' / Archive File Name \n", - "DATAMD5 = 'Not computed' / MD5 checksum \n", - "OBID1 = 3250018 / Observation block ID \n", - "PROG_ID = '109.238W.003' / ESO programme identification \n", - "PROV1 = 'MUSE.2022-06-24T08:46:05.083.fits' \n", - "PROV2 = 'MUSE.2022-06-24T09:12:43.926.fits' \n", - "ASSON1 = 'MU_SIMC_3250018_2022-06-24T08:46:05.083_WFM-NOAO-N_OBJ.fits' \n", - "PRODCATG= 'SCIENCE.CUBE.IFS' / Data product category \n", - "PROCSOFT= 'muse/2.8.6' / ESO pipeline version \n", - "OBSTECH = 'IFU ' / Technique for observation \n", - "FLUXCAL = 'ABSOLUTE' / Type of flux calibration (ABSOLUTE or UNCALIBRA\n", - "WAVELMIN= 475.023779296875 / [nm] Minimum wavelength \n", - "WAVELMAX= 935.023779296875 / [nm] Maximum wavelength \n", - "SPEC_RES= 3026.83548601119 / Spectral resolving power at central wavelength \n", - "SKY_RES = 1.219603947922 / [arcsec] FWHM effective spatial resolution (mea\n", - "SKY_RERR= 0.381083980245825 / [arcsec] Error of SKY_RES (measured) \n", - "PIXNOISE= 3.13368792319848E-20 / [erg.s**(-1).cm**(-2).angstrom**(-1)] pixel-to-\n", - "ABMAGLIM= 22.435214589531 / 5-sigma magnitude limit for point sources \n", - "REFERENC= ' ' / Reference publication \n", - "HIERARCH ESO OBS AIRM = 2. / Req. max. airmass \n", - "HIERARCH ESO OBS AMBI FWHM = 2. / Req. max. seeing \n", - "HIERARCH ESO OBS AMBI TRANS = '4THK ' / Req. sky transparency \n", - "HIERARCH ESO OBS AOMODE = 'NO_AO ' / Req. AO mode \n", - "HIERARCH ESO OBS CONTAINER ID = 3250016 / Scheduling container ID \n", - "HIERARCH ESO OBS CONTAINER TYPE = 'G ' / Scheduling container type \n", - "HIERARCH ESO OBS DID = 'ESO-VLT-DIC.OBS-2.2' / OBS Dictionary \n", - "HIERARCH ESO OBS EXECTIME = 3565 / Expected execution time \n", - "HIERARCH ESO OBS GRP = '0 ' / linked blocks \n", - "HIERARCH ESO OBS ID = 3250018 / Observation block ID \n", - "HIERARCH ESO OBS MOON DIST = 30 / Req. min. angular dist. from moon [deg] \n", - "HIERARCH ESO OBS MOON FLI = 1. / Req. max. fractional lunar illum. \n", - "HIERARCH ESO OBS NAME = 'WFM_J0141-5427_OB1' / OB name \n", - "HIERARCH ESO OBS NTPL = 2 / Number of templates within OB \n", - "HIERARCH ESO OBS OBSERVER = 'UNKNOWN ' / Observer Name \n", - "HIERARCH ESO OBS PI-COI ID = 80093 / ESO internal PI-COI ID \n", - "HIERARCH ESO OBS PI-COI NAME = 'UNKNOWN ' / PI-COI name \n", - "HIERARCH ESO OBS PROG ID = '109.238W.003' / ESO program identification \n", - "HIERARCH ESO OBS START = '2022-06-24T08:36:51' / OB start time \n", - "HIERARCH ESO OBS TARG NAME = 'J0141-5427' / OB target name \n", - "HIERARCH ESO OBS TPLNO = 2 / Template number within OB \n", - "HIERARCH ESO OBS TWILIGHT = 0 / Req. twilight \n", - "HIERARCH ESO OBS WATERVAPOUR = 30. / Req. water vapour \n", - "HIERARCH ESO TPL DID = 'ESO-VLT-DIC.TPL-1.9' / Data dictionary for TPL \n", - "HIERARCH ESO TPL EXPNO = 1 / Exposure number within template \n", - "HIERARCH ESO TPL ID = 'MUSE_wfm-noao_obs_genericoffset' / Template signature ID \n", - "HIERARCH ESO TPL NAME = 'Observation in WFM with user defined offsets' / Templat\n", - "HIERARCH ESO TPL NEXP = 2 / Number of exposures within template \n", - "HIERARCH ESO TPL PRESEQ = 'MUSE_obs_offset.seq' / Sequencer script \n", - "HIERARCH ESO TPL START = '2022-06-24T08:45:45' / TPL start time \n", - "HIERARCH ESO TPL VERSION = '$Revision: 297587 $' / Version of the template \n", - "HIERARCH ESO TEL AG TYPE = 'FIELD_STAB' / Autoguiding type \n", - "HIERARCH ESO TEL AIRM END = 1.41 / Airmass at end \n", - "HIERARCH ESO TEL AIRM START = 1.503 / Airmass at start \n", - "HIERARCH ESO TEL ALT = 41.659 / [deg] Alt angle at start \n", - "HIERARCH ESO TEL AMBI FWHM END = 1.21 / [arcsec] Observatory Seeing queried from\n", - "HIERARCH ESO TEL AMBI FWHM START = 1.4 / [arcsec] Observatory Seeing queried fr \n", - "HIERARCH ESO TEL AMBI IRSKY TEMP = -90.6 / Temperature of the IR sky, from radio\n", - "HIERARCH ESO TEL AMBI IWV END = 1.77 / Integrated Water Vapor \n", - "HIERARCH ESO TEL AMBI IWV START = 1.76 / Integrated Water Vapor \n", - "HIERARCH ESO TEL AMBI IWV30D END = 1.83 / IWV at 30deg elev. \n", - "HIERARCH ESO TEL AMBI IWV30D START = 1.82 / IWV at 30deg elev. \n", - "HIERARCH ESO TEL AMBI IWV30DSTD END = 0.02 / IWV at 30deg elev. \n", - "HIERARCH ESO TEL AMBI IWV30DSTD START = 0.02 / IWV at 30deg elev. \n", - "HIERARCH ESO TEL AMBI IWVSTD END = 0.01 / Standard Deviation of Integrated Water\n", - "HIERARCH ESO TEL AMBI IWVSTD START = 0.01 / Standard Deviation of Integrated Wat\n", - "HIERARCH ESO TEL AMBI PRES END = 742.1 / [hPa] Observatory ambient air pressure \n", - "HIERARCH ESO TEL AMBI PRES START = 742. / [hPa] Observatory ambient air pressu \n", - "HIERARCH ESO TEL AMBI RHUM = 8. / [%] Observatory ambient relative humidity que \n", - "HIERARCH ESO TEL AMBI TAU0 = 0.0024 / [s] Average coherence time \n", - "HIERARCH ESO TEL AMBI TEMP = 8.27 / [deg C] Observatory ambient temperature quer\n", - "HIERARCH ESO TEL AMBI WINDDIR = 9. / [deg] Observatory ambient wind direction q \n", - "HIERARCH ESO TEL AMBI WINDSP = 10.9 / [m/s] Observatory ambient wind speed quer \n", - "HIERARCH ESO TEL AZ = 322.049 / [deg] Az angle at start S=0,W=90 \n", - "HIERARCH ESO TEL CHOP ST = F / True when chopping is active \n", - "HIERARCH ESO TEL DATE = '2000-01-01T00:00:00' / TCS installation date \n", - "HIERARCH ESO TEL DID = 'ESO-VLT-DIC.TCS' / Data dictionary for TEL \n", - "HIERARCH ESO TEL DOME STATUS = 'FULLY-OPEN' / Dome status \n", - "HIERARCH ESO TEL FO POS = 0. / Adapter focus position during tracking \n", - "HIERARCH ESO TEL FOCU ID = 'NB ' / Telescope focus station ID \n", - "HIERARCH ESO TEL FOCU LEN = 121.561 / [m] Focal length \n", - "HIERARCH ESO TEL FOCU SCALE = 1.705 / [arcsec/mm] Focal scale \n", - "HIERARCH ESO TEL FOCU VALUE = -18.896 / [mm] M2 setting \n", - "HIERARCH ESO TEL GEOELEV = 2648. / [m] Elevation above sea level \n", - "HIERARCH ESO TEL GEOLAT = -24.627 / [deg] Tel geo latitute (+=North) \n", - "HIERARCH ESO TEL GEOLON = -70.404 / [deg] Tel geo longitude (+=East) \n", - "HIERARCH ESO TEL IA FWHM = 1.15 / [arcsec] Delivered seeing corrected by airmass\n", - "HIERARCH ESO TEL IA FWHMLIN = 1.25 / Delivered seeing on IA detector (linear fit\n", - "HIERARCH ESO TEL IA FWHMLINOBS = 1.54 / Delivered seeing on IA detector (linear \n", - "HIERARCH ESO TEL ID = 'v 347434' / TCS version number \n", - "HIERARCH ESO TEL MOON DEC = 14.50316 / [deg] 14:30:11.3 DEC (J2000) \n", - "HIERARCH ESO TEL MOON RA = 39.340606 / [deg] 02:37:21.7 RA (J2000) \n", - "HIERARCH ESO TEL OPER = 'I, Condor' / Telescope Operator \n", - "HIERARCH ESO TEL PARANG END = -67.298 / [deg] Parallactic angle at end \n", - "HIERARCH ESO TEL PARANG START = -73.545 / [deg] Parallactic angle at start \n", - "HIERARCH ESO TEL ROT ALTAZTRACK = T / Track rotator on alt/az instead of Alpha/D\n", - "HIERARCH ESO TEL TARG ALPHA = 14132.4 / Alpha coordinate for the target \n", - "HIERARCH ESO TEL TARG COORDTYPE = 'M ' / Coordinate type (M=mean A=apparen\n", - "HIERARCH ESO TEL TARG DELTA = -542749.9 / Delta coordinate for the target \n", - "HIERARCH ESO TEL TARG EPOCH = 2000. / [yr] Epoch 1950 or 2000 \n", - "HIERARCH ESO TEL TARG EPOCHSYSTEM = 'J ' / Epoch system (J=Julian / B=Bess\n", - "HIERARCH ESO TEL TARG EQUINOX = 2000. / [yr] Equinox \n", - "HIERARCH ESO TEL TARG PARALLAX = 0. / [arcsec] Parallax \n", - "HIERARCH ESO TEL TARG PMA = 0. / [arcsec/yr] Proper Motion Alpha \n", - "HIERARCH ESO TEL TARG PMD = 0. / [arcsec/yr] Proper motion Delta \n", - "HIERARCH ESO TEL TARG RADVEL = 0. / [km/s] Radial velocity \n", - "HIERARCH ESO TEL TH M1 TEMP = 6.83 / [deg C] M1 superficial temperature \n", - "HIERARCH ESO TEL TRAK STATUS = 'NORMAL ' / Tracking status \n", - "HIERARCH ESO INS ADC1 DEC = -542050.35316 / [deg] Telescope declination \n", - "HIERARCH ESO INS ADC1 ENC END = 190673 / [Enc] ADC encoder position at end \n", - "HIERARCH ESO INS ADC1 ENC START = 190673 / [Enc] ADC encoder position at start \n", - "HIERARCH ESO INS ADC1 END = -89.9902 / [deg] ADC position at end \n", - "HIERARCH ESO INS ADC1 MODE = 'OFF ' / ADC mode \n", - "HIERARCH ESO INS ADC1 RA = 14222.377677 / [deg] Telescope right ascension \n", - "HIERARCH ESO INS ADC1 START = -89.99 / [deg] ADC position at start \n", - "HIERARCH ESO INS ADC2 DEC = -542050.35316 / [deg] Telescope declination \n", - "HIERARCH ESO INS ADC2 ENC END = 230673 / [Enc] ADC encoder position at end \n", - "HIERARCH ESO INS ADC2 ENC START = 230673 / [Enc] ADC encoder position at start \n", - "HIERARCH ESO INS ADC2 END = -270.005 / [deg] ADC position at end \n", - "HIERARCH ESO INS ADC2 MODE = 'OFF ' / ADC mode \n", - "HIERARCH ESO INS ADC2 RA = 14222.377677 / [deg] Telescope right ascension \n", - "HIERARCH ESO INS ADC2 START = -270.005 / [deg] ADC position at start \n", - "HIERARCH ESO INS AMPL1 ID = 'ampl1 ' / Pico-amplifier ID \n", - "HIERARCH ESO INS AMPL1 SWSIM = F / If T, pico-amplifier software simulated \n", - "HIERARCH ESO INS AMPL2 FILTER = 'Kron_V ' / Name of filter in front of PD2 \n", - "HIERARCH ESO INS AMPL2 ID = 'ampl2 ' / Pico-amplifier ID \n", - "HIERARCH ESO INS AMPL2 SWSIM = F / If T, pico-amplifier software simulated \n", - "HIERARCH ESO INS DATE = '2000-06-16' / Instrument release date (yyyy-mm-dd). \n", - "HIERARCH ESO INS DID1 = 'MUSE_ICS-351426' / Data dictionary for INSi \n", - "HIERARCH ESO INS DID2 = 'PRIMARY-FITS-1.2' / Data dictionary for INSi \n", - "HIERARCH ESO INS DROT DEC = -542050.35316 / [deg] Telescope declination \n", - "HIERARCH ESO INS DROT ENC END = 3563477 / [Enc] Derotator encoder position at en\n", - "HIERARCH ESO INS DROT ENC START = 5396364 / [Enc] Derotator encoder position at \n", - "HIERARCH ESO INS DROT END = -348.874 / [deg] Derotator physical position at end \n", - "HIERARCH ESO INS DROT MODE = 'SKY ' / Instrument derotator mode \n", - "HIERARCH ESO INS DROT POSANG = 0. / [deg] Derotator position angle \n", - "HIERARCH ESO INS DROT RA = 14222.377677 / [deg] Telescope right ascension \n", - "HIERARCH ESO INS DROT START = -344.0479 / [deg] Derotator physical position at s\n", - "HIERARCH ESO INS ID = 'MUSE/176642' / Instrument ID \n", - "HIERARCH ESO INS IFU1 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU1 CHAN = 2 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU1 DV ID = '16 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU1 ID = '01 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU1 ISS ID = '24 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU1 PREAMP ID = '36 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU1 SPS ID = '01 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU1 VPHG ID = '08 ' / Volume Phase Holographic Grating ID\n", - "HIERARCH ESO INS IFU10 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU10 CHAN = 3 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU10 DV ID = '25 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU10 ID = '10 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU10 ISS ID = '10 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU10 PREAMP ID = '29 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU10 SPS ID = '10 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU10 VPHG ID = '19 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU11 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU11 CHAN = 12 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU11 DV ID = '10 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU11 ID = '11 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU11 ISS ID = '03 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU11 PREAMP ID = '55 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU11 SPS ID = '11 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU11 VPHG ID = '15 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU12 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU12 CHAN = 7 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU12 DV ID = '21 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU12 ID = '12 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU12 ISS ID = '09 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU12 PREAMP ID = '50 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU12 SPS ID = '12 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU12 VPHG ID = '21 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU13 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU13 CHAN = 21 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU13 DV ID = '22 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU13 ID = '13 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU13 ISS ID = '08 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU13 PREAMP ID = '78 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU13 SPS ID = '13 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU13 VPHG ID = '18 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU14 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU14 CHAN = 5 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU14 DV ID = '23 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU14 ID = '14 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU14 ISS ID = '12 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU14 PREAMP ID = '34 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU14 SPS ID = '14 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU14 VPHG ID = '20 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU15 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU15 CHAN = 15 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU15 DV ID = '26 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU15 ID = '15 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU15 ISS ID = '15 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU15 PREAMP ID = '66 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU15 SPS ID = '15 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU15 VPHG ID = '22 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU16 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU16 CHAN = 18 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU16 DV ID = '27 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU16 ID = '16 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU16 ISS ID = '16 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU16 PREAMP ID = '57 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU16 SPS ID = '16 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU16 VPHG ID = '17 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU17 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU17 CHAN = 13 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU17 DV ID = '17 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU17 ID = '17 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU17 ISS ID = '13 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU17 PREAMP ID = '46 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU17 SPS ID = '17 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU17 VPHG ID = '16 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU18 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU18 CHAN = 9 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU18 DV ID = '08 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU18 ID = '18 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU18 ISS ID = '19 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU18 PREAMP ID = '43 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU18 SPS ID = '18 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU18 VPHG ID = '26 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU19 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU19 CHAN = 14 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU19 DV ID = '13 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU19 ID = '19 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU19 ISS ID = '18 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU19 PREAMP ID = '37 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU19 SPS ID = '19 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU19 VPHG ID = '23 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU2 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU2 CHAN = 6 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU2 DV ID = '24 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU2 ID = '02 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU2 ISS ID = '06 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU2 PREAMP ID = '52 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU2 SPS ID = '02 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU2 VPHG ID = '03 ' / Volume Phase Holographic Grating ID\n", - "HIERARCH ESO INS IFU20 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU20 CHAN = 10 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU20 DV ID = '20 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU20 ID = '20 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU20 ISS ID = '20 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU20 PREAMP ID = '38 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU20 SPS ID = '20 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU20 VPHG ID = '24 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU21 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU21 CHAN = 11 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU21 DV ID = '15 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU21 ID = '21 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU21 ISS ID = '17 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU21 PREAMP ID = '23 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU21 SPS ID = '21 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU21 VPHG ID = '27 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU22 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU22 CHAN = 24 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU22 DV ID = '14 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU22 ID = '22 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU22 ISS ID = '22 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU22 PREAMP ID = '54 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU22 SPS ID = '22 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU22 VPHG ID = '11 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU23 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU23 CHAN = 23 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU23 DV ID = '18 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU23 ID = '23 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU23 ISS ID = '23 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU23 PREAMP ID = '60 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU23 SPS ID = '23 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU23 VPHG ID = '31 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU24 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU24 CHAN = 1 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU24 DV ID = '12 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU24 ID = '24 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU24 ISS ID = '02 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU24 PREAMP ID = '24 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU24 SPS ID = '24 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU24 VPHG ID = '10 ' / Volume Phase Holographic Grating I\n", - "HIERARCH ESO INS IFU3 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU3 CHAN = 8 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU3 DV ID = '11 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU3 ID = '03 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU3 ISS ID = '14 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU3 PREAMP ID = '33 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU3 SPS ID = '03 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU3 VPHG ID = '14 ' / Volume Phase Holographic Grating ID\n", - "HIERARCH ESO INS IFU4 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU4 CHAN = 4 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU4 DV ID = '03 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU4 ID = '04 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU4 ISS ID = '05 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU4 PREAMP ID = '59 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU4 SPS ID = '04 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU4 VPHG ID = '07 ' / Volume Phase Holographic Grating ID\n", - "HIERARCH ESO INS IFU5 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU5 CHAN = 22 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU5 DV ID = '09 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU5 ID = '05 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU5 ISS ID = '11 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU5 PREAMP ID = '77 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU5 SPS ID = '05 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU5 VPHG ID = '04 ' / Volume Phase Holographic Grating ID\n", - "HIERARCH ESO INS IFU6 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU6 CHAN = 20 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU6 DV ID = '07 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU6 ID = '06 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU6 ISS ID = '01 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU6 PREAMP ID = '79 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU6 SPS ID = '06 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU6 VPHG ID = '06 ' / Volume Phase Holographic Grating ID\n", - "HIERARCH ESO INS IFU7 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU7 CHAN = 17 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU7 DV ID = '05 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU7 ID = '07 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU7 ISS ID = '07 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU7 PREAMP ID = '63 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU7 SPS ID = '07 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU7 VPHG ID = '13 ' / Volume Phase Holographic Grating ID\n", - "HIERARCH ESO INS IFU8 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU8 CHAN = 16 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU8 DV ID = '06 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU8 ID = '08 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU8 ISS ID = '04 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU8 PREAMP ID = '56 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU8 SPS ID = '08 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU8 VPHG ID = '05 ' / Volume Phase Holographic Grating ID\n", - "HIERARCH ESO INS IFU9 CABLE ID = '-1 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU9 CHAN = 19 / Integral Field Unit channel \n", - "HIERARCH ESO INS IFU9 DV ID = '19 ' / Detector Vessel ID \n", - "HIERARCH ESO INS IFU9 ID = '09 ' / Integral Field Unit ID \n", - "HIERARCH ESO INS IFU9 ISS ID = '21 ' / Image Slicer System ID \n", - "HIERARCH ESO INS IFU9 PREAMP ID = '47 ' / Detector cable ID \n", - "HIERARCH ESO INS IFU9 SPS ID = '09 ' / Spectograph System ID \n", - "HIERARCH ESO INS IFU9 VPHG ID = '32 ' / Volume Phase Holographic Grating ID\n", - "HIERARCH ESO INS LAMPNUM = 6 / Number of lamps \n", - "HIERARCH ESO INS MODE = 'WFM-NOAO-N' / Instrument mode used \n", - "HIERARCH ESO INS OPTI1 ID = '1 ' / Optical function unique ID \n", - "HIERARCH ESO INS OPTI1 NAME = 'Blue ' / Pupil Filter Wheel filter name \n", - "HIERARCH ESO INS OPTI1 NO = 1 / Pupil Filter Wheel slot number \n", - "HIERARCH ESO INS OPTI1 TYPE = 'FILTER ' / Pupil Filter Wheel element type \n", - "HIERARCH ESO INS OPTI2 ID = '2 ' / Optical function unique ID \n", - "HIERARCH ESO INS OPTI2 NAME = 'WFM ' / Mode Switching Unit field mode \n", - "HIERARCH ESO INS OPTI2 NO = 2 / Mode Switching Unit position \n", - "HIERARCH ESO INS OPTI2 TYPE = 'FILTER ' / Optical function element \n", - "HIERARCH ESO INS OPTI3 ID = '1 ' / Optical function unique ID \n", - "HIERARCH ESO INS OPTI3 NAME = 'WFM ' / Calibration Unit Pickup Mirror Status\n", - "HIERARCH ESO INS OPTI3 NO = 1 / Calibration Pickup Element position \n", - "HIERARCH ESO INS OPTI3 TYPE = 'FREE ' / Calibration Pickup Element type \n", - "HIERARCH ESO INS OPTI4 ID = '4 ' / Optical function unique ID \n", - "HIERARCH ESO INS OPTI4 NAME = 'Clear ' / CU Focal Plan mask Wheel mask name \n", - "HIERARCH ESO INS OPTI4 NO = 4 / CU Focal Plan Mask Wheel slot number \n", - "HIERARCH ESO INS OPTI4 TYPE = 'MASK ' / Optical function element \n", - "HIERARCH ESO INS PATH = ' ' / Optical path used \n", - "HIERARCH ESO INS POS1 ENC = 739738 / [Enc] Position function absolute position \n", - "HIERARCH ESO INS POS1 POS = 12.9 / [mm] Focusing stage position \n", - "HIERARCH ESO INS POS2 ENC = 706631 / [Enc] Position function absolute position \n", - "HIERARCH ESO INS POS2 POS = 14.541 / [mm] Focal Mask Alignment X position \n", - "HIERARCH ESO INS POS3 ENC = 672225 / [Enc] Position function absolute position \n", - "HIERARCH ESO INS POS3 POS = 13.833 / [mm] Focal Mask Alignment Y Position \n", - "HIERARCH ESO INS POS4 ENC = 675481 / [Enc] Position function absolute position \n", - "HIERARCH ESO INS POS4 POS = 13.9 / [mm] Focal Mask Alignment Z Position \n", - "HIERARCH ESO INS PRES1 ID = 'ERP1 ' / Pressure sensor ID \n", - "HIERARCH ESO INS PRES1 NAME = 'Right Enclosure Diff Pressure' / Pressure sensor \n", - "HIERARCH ESO INS PRES1 VAL = -3.99 / [mBar] Right enclosure diff. pressure \n", - "HIERARCH ESO INS PRES13 VAL = 1035.14 / [mBar] Pre-vacuum pump pressure \n", - "HIERARCH ESO INS PRES2 ID = 'ELP1 ' / Pressure sensor ID \n", - "HIERARCH ESO INS PRES2 NAME = 'Left Enclosure Diff Pressure' / Pressure sensor n\n", - "HIERARCH ESO INS PRES2 VAL = -1.14 / [mBar] Left enclosure diff. pressure \n", - "HIERARCH ESO INS PRES21 VAL = 8.4E-06 / [mBar] Detector 1 pressure \n", - "HIERARCH ESO INS PRES23 VAL = 1.4E-05 / [mBar] Detector 3 pressure \n", - "HIERARCH ESO INS PRES25 VAL = 7.9E-06 / [mBar] Detector 5 pressure \n", - "HIERARCH ESO INS PRES27 VAL = 3.6E-06 / [mBar] Detector 7 pressure \n", - "HIERARCH ESO INS PRES29 VAL = 1.5E-05 / [mBar] Detector 9 pressure \n", - "HIERARCH ESO INS PRES31 VAL = 1.2E-05 / [mBar] Detector 11 pressure \n", - "HIERARCH ESO INS PRES33 VAL = 3.1E-06 / [mBar] Detector 13 pressure \n", - "HIERARCH ESO INS PRES35 VAL = 5.2E-06 / [mBar] Detector 15 pressure \n", - "HIERARCH ESO INS PRES37 VAL = 4.4E-06 / [mBar] Detector 17 pressure \n", - "HIERARCH ESO INS PRES39 VAL = 4.7E-06 / [mBar] Detector 19 pressure \n", - "HIERARCH ESO INS PRES41 VAL = 7.8E-06 / [mBar] Detector 21 pressure \n", - "HIERARCH ESO INS PRES43 VAL = 4.8E-06 / [mBar] Detector 23 pressure \n", - "HIERARCH ESO INS PRES45 VAL = 2E-06 / [mBar] Detector 2 pressure \n", - "HIERARCH ESO INS PRES47 VAL = 2.7E-05 / [mBar] Detector 4 pressure \n", - "HIERARCH ESO INS PRES49 VAL = 9.2E-06 / [mBar] Detector 6 pressure \n", - "HIERARCH ESO INS PRES51 VAL = 1.5E-05 / [mBar] Detector 8 pressure \n", - "HIERARCH ESO INS PRES53 VAL = 2.8E-05 / [mBar] Detector 10 pressure \n", - "HIERARCH ESO INS PRES55 VAL = 8.2E-06 / [mBar] Detector 12 pressure \n", - "HIERARCH ESO INS PRES57 VAL = 5.6E-06 / [mBar] Detector 14 pressure \n", - "HIERARCH ESO INS PRES59 VAL = 7.2E-06 / [mBar] Detector 16 pressure \n", - "HIERARCH ESO INS PRES61 VAL = 6.6E-06 / [mBar] Detector 18 pressure \n", - "HIERARCH ESO INS PRES63 VAL = 6.3E-06 / [mBar] Detector 20 pressure \n", - "HIERARCH ESO INS PRES65 VAL = 2.7E-05 / [mBar] Detector 22 pressure \n", - "HIERARCH ESO INS PRES67 VAL = 2.4E-06 / [mBar] Detector 24 pressure \n", - "HIERARCH ESO INS SENS1 ID = 'CURL1 ' / Sensor ID \n", - "HIERARCH ESO INS SENS1 NAME = 'INS LAMP1 Current' / Sensor common name \n", - "HIERARCH ESO INS SENS1 VAL = 3 / [10-1 A] Lamp 1 current value \n", - "HIERARCH ESO INS SENS10 ID = 'TTL3 ' / Sensor ID \n", - "HIERARCH ESO INS SENS10 NAME = 'INS LAMP3 Total Time' / Sensor common name \n", - "HIERARCH ESO INS SENS10 VAL = 302. / [h] Lamp #3 total time \n", - "HIERARCH ESO INS SENS11 ID = 'OVTL3 ' / Sensor ID \n", - "HIERARCH ESO INS SENS11 NAME = 'INS LAMP3 Over Temp. Alarm' / Sensor common name\n", - "HIERARCH ESO INS SENS11 VAL = F / Lamp #3 over temperature alarm \n", - "HIERARCH ESO INS SENS12 ID = 'ALTL3 ' / Sensor ID \n", - "HIERARCH ESO INS SENS12 NAME = 'INS LAMP3 Temp. Latched Alarm' / Sensor common n\n", - "HIERARCH ESO INS SENS12 VAL = F / Lamp #3 over temperature latched alarm \n", - "HIERARCH ESO INS SENS13 ID = 'CURL4 ' / Sensor ID \n", - "HIERARCH ESO INS SENS13 NAME = 'INS LAMP4 Current' / Sensor common name \n", - "HIERARCH ESO INS SENS13 VAL = 21 / [10-1 mA] Lamp #4 current value \n", - "HIERARCH ESO INS SENS14 ID = 'TTL4 ' / Sensor ID \n", - "HIERARCH ESO INS SENS14 NAME = 'INS LAMP4 Total Time' / Sensor common name \n", - "HIERARCH ESO INS SENS14 VAL = 454. / [h] Lamp #4 total time \n", - "HIERARCH ESO INS SENS15 ID = 'OVTL4 ' / Sensor ID \n", - "HIERARCH ESO INS SENS15 NAME = 'INS LAMP4 Over Temp. Alarm' / Sensor common name\n", - "HIERARCH ESO INS SENS15 VAL = F / Lamp #4 over temperature alarm \n", - "HIERARCH ESO INS SENS16 ID = 'ALTL4 ' / Sensor ID \n", - "HIERARCH ESO INS SENS16 NAME = 'INS LAMP4 Temp. Latched Alarm' / Sensor common n\n", - "HIERARCH ESO INS SENS16 VAL = F / Lamp #4 over temperature latched alarm \n", - "HIERARCH ESO INS SENS17 ID = 'CURL5 ' / Sensor ID \n", - "HIERARCH ESO INS SENS17 NAME = 'INS LAMP5 Current' / Sensor common name \n", - "HIERARCH ESO INS SENS17 VAL = 27 / [10-2 A] Lamp #5 current value \n", - "HIERARCH ESO INS SENS18 ID = 'TTL5 ' / Sensor ID \n", - "HIERARCH ESO INS SENS18 NAME = 'INS LAMP5 Total Time' / Sensor common name \n", - "HIERARCH ESO INS SENS18 VAL = 1459. / [h] Lamp #5 total time \n", - "HIERARCH ESO INS SENS19 ID = 'OVTL5 ' / Sensor ID \n", - "HIERARCH ESO INS SENS19 NAME = 'INS LAMP5 Over Temp. Alarm' / Sensor common name\n", - "HIERARCH ESO INS SENS19 VAL = F / Lamp #5 over temperature alarm \n", - "HIERARCH ESO INS SENS2 ID = 'TTL1 ' / Sensor ID \n", - "HIERARCH ESO INS SENS2 NAME = 'INS LAMP1 Total Time' / Sensor common name \n", - "HIERARCH ESO INS SENS2 VAL = 3160. / [h] Lamp #1 total time \n", - "HIERARCH ESO INS SENS20 ID = 'ALTL5 ' / Sensor ID \n", - "HIERARCH ESO INS SENS20 NAME = 'INS LAMP5 Temp. Latched Alarm' / Sensor common n\n", - "HIERARCH ESO INS SENS20 VAL = F / Lamp #5 over temperature latched alarm \n", - "HIERARCH ESO INS SENS21 ID = 'CURL6 ' / Sensor ID \n", - "HIERARCH ESO INS SENS21 NAME = 'INS LAMP6 Current' / Sensor common name \n", - "HIERARCH ESO INS SENS21 VAL = 32 / [10-2 A] Lamp #6 current value \n", - "HIERARCH ESO INS SENS22 ID = 'TTL6 ' / Sensor ID \n", - "HIERARCH ESO INS SENS22 NAME = 'INS LAMP6 Total Time' / Sensor common name \n", - "HIERARCH ESO INS SENS22 VAL = 3448. / [h] Lamp #6 total time \n", - "HIERARCH ESO INS SENS23 ID = 'OVTL6 ' / Sensor ID \n", - "HIERARCH ESO INS SENS23 NAME = 'INS LAMP6 Over Temp. Alarm' / Sensor common name\n", - "HIERARCH ESO INS SENS23 VAL = F / Lamp #6 over temperature alarm \n", - "HIERARCH ESO INS SENS24 ID = 'ALTL6 ' / Sensor ID \n", - "HIERARCH ESO INS SENS24 NAME = 'INS LAMP6 Temp. Latched Alarm' / Sensor common n\n", - "HIERARCH ESO INS SENS24 VAL = F / Lamp #6 over temperature latched alarm \n", - "HIERARCH ESO INS SENS3 ID = 'OVTL1 ' / Sensor ID \n", - "HIERARCH ESO INS SENS3 NAME = 'INS LAMP1 Over Temp. Alarm' / Sensor common name \n", - "HIERARCH ESO INS SENS3 VAL = F / Lamp #1 over temperature alarm \n", - "HIERARCH ESO INS SENS31 ID = 'CAW1 ' / Sensor ID \n", - "HIERARCH ESO INS SENS31 NAME = 'Cooling Warning 1' / Sensor common name \n", - "HIERARCH ESO INS SENS31 STAT = F / Cabinet cooling system warning \n", - "HIERARCH ESO INS SENS32 ID = 'DOR1 ' / Sensor ID \n", - "HIERARCH ESO INS SENS32 NAME = 'Door 1 Control' / Sensor common name \n", - "HIERARCH ESO INS SENS32 STAT = F / Cabinet front door switch \n", - "HIERARCH ESO INS SENS33 ID = 'DOR2 ' / Sensor ID \n", - "HIERARCH ESO INS SENS33 NAME = 'Door 2 Control' / Sensor common name \n", - "HIERARCH ESO INS SENS33 STAT = F / Cabinet rear door switch \n", - "HIERARCH ESO INS SENS34 ID = 'CAL1 ' / Sensor ID \n", - "HIERARCH ESO INS SENS34 NAME = 'Cooling Alarm 1' / Sensor common name \n", - "HIERARCH ESO INS SENS34 STAT = F / Cabinet cooling system alarm \n", - "HIERARCH ESO INS SENS4 ID = 'ALTL1 ' / Sensor ID \n", - "HIERARCH ESO INS SENS4 NAME = 'INS LAMP1 Temp. Latched Alarm' / Sensor common na\n", - "HIERARCH ESO INS SENS4 VAL = F / Lamp #1 over temperature latched alarm \n", - "HIERARCH ESO INS SENS40 ID = 'CAF2 ' / Sensor ID \n", - "HIERARCH ESO INS SENS40 NAME = 'Flow Rate' / Sensor common name \n", - "HIERARCH ESO INS SENS40 VAL = 125. / [l/h] Cabinet flow rate \n", - "HIERARCH ESO INS SENS46 ID = 'XMAS1 ' / Sensor ID \n", - "HIERARCH ESO INS SENS46 NAME = 'Xtra Muse Aperture Shutter' / Sensor common name\n", - "HIERARCH ESO INS SENS46 STAT = F / Xtra Muse Aperture Shutter switch \n", - "HIERARCH ESO INS SENS5 ID = 'CURL2 ' / Sensor ID \n", - "HIERARCH ESO INS SENS5 NAME = 'INS LAMP2 Current' / Sensor common name \n", - "HIERARCH ESO INS SENS5 VAL = 3 / [10-1 A] Lamp #2 current value \n", - "HIERARCH ESO INS SENS51 ID = 'ECH1 ' / Sensor ID \n", - "HIERARCH ESO INS SENS51 NAME = 'Fore Optics Hygrometry' / Sensor common name \n", - "HIERARCH ESO INS SENS51 VAL = 12.93 / [%] Fore Optics hygrometry \n", - "HIERARCH ESO INS SENS6 ID = 'TTL2 ' / Sensor ID \n", - "HIERARCH ESO INS SENS6 NAME = 'INS LAMP2 Total Time' / Sensor common name \n", - "HIERARCH ESO INS SENS6 VAL = 8968. / [h] Lamp #2 total time \n", - "HIERARCH ESO INS SENS7 ID = 'OVTL2 ' / Sensor ID \n", - "HIERARCH ESO INS SENS7 NAME = 'INS LAMP2 Over Temp. Alarm' / Sensor common name \n", - "HIERARCH ESO INS SENS7 VAL = F / Lamp #2 over temperature alarm \n", - "HIERARCH ESO INS SENS8 ID = 'ALTL2 ' / Sensor ID \n", - "HIERARCH ESO INS SENS8 NAME = 'INS LAMP2 Temp. Latched Alarm' / Sensor common na\n", - "HIERARCH ESO INS SENS8 VAL = F / Lamp #2 over temperature latched alarm \n", - "HIERARCH ESO INS SENS80 VAL = F / Pre-vacuum pump status \n", - "HIERARCH ESO INS SENS81 VAL = 2 / Turbo pump speed \n", - "HIERARCH ESO INS SENS9 ID = 'CURL3 ' / Sensor ID \n", - "HIERARCH ESO INS SENS9 NAME = 'INS LAMP3 Current' / Sensor common name \n", - "HIERARCH ESO INS SENS9 VAL = 18 / [10-1 mA] Lamp #3 current value \n", - "HIERARCH ESO INS SENSOR1 ID = 'clx1 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR1 NAME = 'INS LAMP1 Data' / Sensor device common name \n", - "HIERARCH ESO INS SENSOR10 ID = 'hsk1 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR10 NAME = 'HSK Encl/IFU env' / Sensor device common name \n", - "HIERARCH ESO INS SENSOR13 ID = 'cryom ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR13 NAME = 'Cryogenic controller monitoring' / Sensor devi\n", - "HIERARCH ESO INS SENSOR14 ID = 'cryo11 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR14 NAME = 'IDS1 JUMO monitoring' / Sensor device common n\n", - "HIERARCH ESO INS SENSOR15 ID = 'cryo12 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR15 NAME = 'IDS2 JUMO monitoring' / Sensor device common n\n", - "HIERARCH ESO INS SENSOR2 ID = 'clx2 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR2 NAME = 'INS LAMP2 Data' / Sensor device common name \n", - "HIERARCH ESO INS SENSOR3 ID = 'clx3 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR3 NAME = 'INS LAMP3 Data' / Sensor device common name \n", - "HIERARCH ESO INS SENSOR4 ID = 'clx4 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR4 NAME = 'INS LAMP4 Data' / Sensor device common name \n", - "HIERARCH ESO INS SENSOR5 ID = 'clx5 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR5 NAME = 'INS LAMP5 Data' / Sensor device common name \n", - "HIERARCH ESO INS SENSOR6 ID = 'clx6 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR6 NAME = 'INS LAMP6 Data' / Sensor device common name \n", - "HIERARCH ESO INS SENSOR7 ID = 'dis1 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR7 NAME = 'Cabinet Dig. Sensor' / Sensor device common nam\n", - "HIERARCH ESO INS SENSOR8 ID = 'ccc1 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR8 NAME = 'Cooling controller' / Sensor device common name\n", - "HIERARCH ESO INS SENSOR9 ID = 'dis2 ' / Sensor device unique id \n", - "HIERARCH ESO INS SENSOR9 NAME = 'Safety Switches' / Sensor device common name \n", - "HIERARCH ESO INS SHUT1 ID = 'CSH1 ' / Lamp shutter ID \n", - "HIERARCH ESO INS SHUT1 NAME = 'ContB ' / Lamp shutter name \n", - "HIERARCH ESO INS SHUT1 ST = F / Lamp shutter open \n", - "HIERARCH ESO INS SHUT2 ID = 'CSH2 ' / Lamp shutter ID \n", - "HIERARCH ESO INS SHUT2 NAME = 'ContR ' / Lamp shutter name \n", - "HIERARCH ESO INS SHUT2 ST = F / Lamp shutter open \n", - "HIERARCH ESO INS SHUT3 ID = 'CSH3 ' / Lamp shutter ID \n", - "HIERARCH ESO INS SHUT3 NAME = 'Ne ' / Lamp shutter name \n", - "HIERARCH ESO INS SHUT3 ST = F / Lamp shutter open \n", - "HIERARCH ESO INS SHUT4 ID = 'CSH4 ' / Lamp shutter ID \n", - "HIERARCH ESO INS SHUT4 NAME = 'Xe ' / Lamp shutter name \n", - "HIERARCH ESO INS SHUT4 ST = F / Lamp shutter open \n", - "HIERARCH ESO INS SHUT5 ID = 'CSH5 ' / Lamp shutter ID \n", - "HIERARCH ESO INS SHUT5 NAME = 'HgCd ' / Lamp shutter name \n", - "HIERARCH ESO INS SHUT5 ST = F / Lamp shutter open \n", - "HIERARCH ESO INS SHUT6 ID = 'CSH6 ' / Lamp shutter ID \n", - "HIERARCH ESO INS SHUT6 NAME = 'Ne ' / Lamp shutter name \n", - "HIERARCH ESO INS SHUT6 ST = F / Lamp shutter open \n", - "HIERARCH ESO INS SWSIM = 'NORMAL ' / Software simulation \n", - "HIERARCH ESO INS TEMP1 ID = 'CAOT ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP1 NAME = 'Cooling Outlet Temperature' / Temperature sensor \n", - "HIERARCH ESO INS TEMP1 VAL = 7.87 / [C] Cooling outlet temperature \n", - "HIERARCH ESO INS TEMP10 ID = 'ELT2 ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP10 NAME = 'Left Enclosure Temperature 2' / Temperature sens\n", - "HIERARCH ESO INS TEMP10 VAL = 8.03 / [C] Left enclosure temperature #2 \n", - "HIERARCH ESO INS TEMP11 ID = 'ILT1 ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP11 NAME = 'Left IFU Temperature 1' / Temperature sensor nam\n", - "HIERARCH ESO INS TEMP11 VAL = 8.49 / [C] Left IFU temperature \n", - "HIERARCH ESO INS TEMP13 ID = 'ECT1 ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP13 NAME = 'Central Enclosure Temperature 1' / Temperature s\n", - "HIERARCH ESO INS TEMP13 VAL = 8.94 / [C] Central enclosure temperature #1 \n", - "HIERARCH ESO INS TEMP14 ID = 'ECT2 ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP14 NAME = 'Central Enclosure Temperature 2' / Temperature s\n", - "HIERARCH ESO INS TEMP14 VAL = 9.1 / [C] Central enclosure temperature #2 \n", - "HIERARCH ESO INS TEMP16 ID = 'EBT1 ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP16 NAME = 'EBB Crate Temperature' / Temperature sensor name\n", - "HIERARCH ESO INS TEMP16 VAL = 10.12 / [C] EBB crate temperature \n", - "HIERARCH ESO INS TEMP17 ID = 'EBT2 ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP17 NAME = 'Heat Exchanger Temperature' / Temperature sensor\n", - "HIERARCH ESO INS TEMP17 VAL = 20.33 / [C] Heat exchanger temperature \n", - "HIERARCH ESO INS TEMP2 ID = 'CAIT ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP2 NAME = 'Cooling Inlet Temperature' / Temperature sensor n\n", - "HIERARCH ESO INS TEMP2 VAL = 5.2 / [C] Cooling inlet temperature \n", - "HIERARCH ESO INS TEMP21 VAL = 162.98 / [K] Detector 1 temperature \n", - "HIERARCH ESO INS TEMP23 VAL = 163.01 / [K] Detector 3 temperature \n", - "HIERARCH ESO INS TEMP25 VAL = 163. / [K] Detector 5 temperature \n", - "HIERARCH ESO INS TEMP27 VAL = 163.03 / [K] Detector 7 temperature \n", - "HIERARCH ESO INS TEMP29 VAL = 163. / [K] Detector 9 temperature \n", - "HIERARCH ESO INS TEMP3 ID = 'CACT ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP3 NAME = 'Cabinet Temperature' / Temperature sensor name \n", - "HIERARCH ESO INS TEMP3 VAL = 13.22 / [C] Cabinet temperature \n", - "HIERARCH ESO INS TEMP31 VAL = 163. / [K] Detector 11 temperature \n", - "HIERARCH ESO INS TEMP33 VAL = 162.97 / [K] Detector 13 temperature \n", - "HIERARCH ESO INS TEMP35 VAL = 162.96 / [K] Detector 15 temperature \n", - "HIERARCH ESO INS TEMP37 VAL = 162.99 / [K] Detector 17 temperature \n", - "HIERARCH ESO INS TEMP39 VAL = 162.99 / [K] Detector 19 temperature \n", - "HIERARCH ESO INS TEMP4 ID = 'CAAT ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP4 NAME = 'Ambient Temperature' / Temperature sensor name \n", - "HIERARCH ESO INS TEMP4 VAL = 7.63 / [C] Ambient temperature \n", - "HIERARCH ESO INS TEMP41 VAL = 162.99 / [K] Detector 21 temperature \n", - "HIERARCH ESO INS TEMP43 VAL = 163.01 / [K] Detector 23 temperature \n", - "HIERARCH ESO INS TEMP45 VAL = 162.97 / [K] Detector 2 temperature \n", - "HIERARCH ESO INS TEMP47 VAL = 163.02 / [K] Detector 4 temperature \n", - "HIERARCH ESO INS TEMP49 VAL = 163. / [K] Detector 6 temperature \n", - "HIERARCH ESO INS TEMP5 ID = 'ERT1 ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP5 NAME = 'Right Enclosure Temperature 1' / Temperature sens\n", - "HIERARCH ESO INS TEMP5 VAL = 8.92 / [C] Right enclosure temperature #1 \n", - "HIERARCH ESO INS TEMP51 VAL = 162.99 / [K] Detector 8 temperature \n", - "HIERARCH ESO INS TEMP53 VAL = 163.01 / [K] Detector 10 temperature \n", - "HIERARCH ESO INS TEMP55 VAL = 163.01 / [K] Detector 12 temperature \n", - "HIERARCH ESO INS TEMP57 VAL = 163. / [K] Detector 14 temperature \n", - "HIERARCH ESO INS TEMP59 VAL = 163.01 / [K] Detector 16 temperature \n", - "HIERARCH ESO INS TEMP6 ID = 'ERT2 ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP6 NAME = 'Right Enclosure Temperature 2' / Temperature sens\n", - "HIERARCH ESO INS TEMP6 VAL = 8.58 / [C] Right enclosure temperature #2 \n", - "HIERARCH ESO INS TEMP61 VAL = 163. / [K] Detector 18 temperature \n", - "HIERARCH ESO INS TEMP63 VAL = 163. / [K] Detector 20 temperature \n", - "HIERARCH ESO INS TEMP65 VAL = 162.98 / [K] Detector 22 temperature \n", - "HIERARCH ESO INS TEMP67 VAL = 163. / [K] Detector 24 temperature \n", - "HIERARCH ESO INS TEMP7 ID = 'IRT1 ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP7 NAME = 'Right IFU Temperature 1' / Temperature sensor nam\n", - "HIERARCH ESO INS TEMP7 VAL = 8.21 / [C] Right IFU temperature \n", - "HIERARCH ESO INS TEMP9 ID = 'ELT1 ' / Temperature sensor ID \n", - "HIERARCH ESO INS TEMP9 NAME = 'Left Enclosure Temperature 1' / Temperature senso\n", - "HIERARCH ESO INS TEMP9 VAL = 8.41 / [C] Left enclosure temperature #1 \n", - "HIERARCH ESO DET BINX = 1 / Setup binning factor along X \n", - "HIERARCH ESO DET BINY = 1 / Setup binning factor along Y \n", - "HIERARCH ESO DET CHIPS = 24 / Number of chips in the mosaic \n", - "HIERARCH ESO DET DEV1 BOARD1 BCKPL = '000010805B5C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV1 BOARD1 REV = '5.6.4 ' / Revision \n", - "HIERARCH ESO DET DEV1 BOARD1 SERNO = '000013A6CABC' / Serial no (board) \n", - "HIERARCH ESO DET DEV1 BOARD1 TRANS = '00001216DDAF' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV1 BOARD1 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV1 BOARD1 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV1 BOARD2 BCKPL = '000010805B5C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV1 BOARD2 REV = '5.6.4 ' / Revision \n", - "HIERARCH ESO DET DEV1 BOARD2 SERNO = '000013A71E3B' / Serial no (board) \n", - "HIERARCH ESO DET DEV1 BOARD2 TRANS = '00001216BFFA' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV1 BOARD2 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV1 BOARD2 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV1 BOARD3 BCKPL = '000010805B5C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV1 BOARD3 REV = '5.6.4 ' / Revision \n", - "HIERARCH ESO DET DEV1 BOARD3 SERNO = '000013A6DADC' / Serial no (board) \n", - "HIERARCH ESO DET DEV1 BOARD3 TRANS = '00001216DA97' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV1 BOARD3 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV1 BOARD3 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV1 BOARD4 BCKPL = '000010805B5C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV1 BOARD4 REV = '5.6.4 ' / Revision \n", - "HIERARCH ESO DET DEV1 BOARD4 SERNO = '00001216CFAA' / Serial no (board) \n", - "HIERARCH ESO DET DEV1 BOARD4 TRANS = '00001216AA6B' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV1 BOARD4 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV1 BOARD4 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV1 BOARD5 BCKPL = '000010805B5C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV1 BOARD5 REV = '5.6.4 ' / Revision \n", - "HIERARCH ESO DET DEV1 BOARD5 SERNO = '0000163DC5C5' / Serial no (board) \n", - "HIERARCH ESO DET DEV1 BOARD5 TRANS = '00001216C3C2' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV1 BOARD5 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV1 BOARD5 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV1 BOARD6 BCKPL = '000010805B5C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV1 BOARD6 REV = '5.6.4 ' / Revision \n", - "HIERARCH ESO DET DEV1 BOARD6 SERNO = '00001216BFC2' / Serial no (board) \n", - "HIERARCH ESO DET DEV1 BOARD6 TRANS = '00001216DA17' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV1 BOARD6 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV1 BOARD6 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV1 CHIPS = 6 / Number of chips in the mosaic \n", - "HIERARCH ESO DET DEV1 EXP RDTTIME = 47.231 / [s] Image readout time \n", - "HIERARCH ESO DET DEV1 EXP XFERTIM = 47.178 / [s] Image transfer time \n", - "HIERARCH ESO DET DEV1 ID = 'MUSE-NGC1' / Detector system Id \n", - "HIERARCH ESO DET DEV1 OUTPUTS = 24 / Number of outputs \n", - "HIERARCH ESO DET DEV1 REV = '3.1.1 ' / Revision \n", - "HIERARCH ESO DET DEV1 SHUT ID = 'Bonn-01 ' / Shutter unique identifier \n", - "HIERARCH ESO DET DEV1 SHUT TMCLOS = 0.693 / [s] Time taken to close shutter \n", - "HIERARCH ESO DET DEV1 SHUT TMOPEN = 0.693 / [s] Time taken to open shutter \n", - "HIERARCH ESO DET DEV1 SHUT TYPE = 'Bonn ' / Shutter type \n", - "HIERARCH ESO DET DEV1 SOFW BASE = '306134 ' / Base software version \n", - "HIERARCH ESO DET DEV1 SOFW DETMOD = '340662 ' / Detector module revision \n", - "HIERARCH ESO DET DEV1 SOFW MODE = 'NORMAL ' / Software operational mode \n", - "HIERARCH ESO DET DEV1 SOFW OPT = '306134 ' / Optical software version \n", - "HIERARCH ESO DET DEV2 BOARD1 BCKPL = '0000106EDDFC' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV2 BOARD1 SERNO = '000013A6E473' / Serial no (board) \n", - "HIERARCH ESO DET DEV2 BOARD1 TRANS = '00001216DF3B' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV2 BOARD1 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV2 BOARD1 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV2 BOARD2 BCKPL = '0000106EDDFC' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV2 BOARD2 SERNO = '000013A71E1F' / Serial no (board) \n", - "HIERARCH ESO DET DEV2 BOARD2 TRANS = '00001216C06F' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV2 BOARD2 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV2 BOARD2 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV2 BOARD3 BCKPL = '0000106EDDFC' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV2 BOARD3 SERNO = '000013A6C77A' / Serial no (board) \n", - "HIERARCH ESO DET DEV2 BOARD3 TRANS = '00001216C01D' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV2 BOARD3 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV2 BOARD3 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV2 BOARD4 BCKPL = '0000106EDDFC' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV2 BOARD4 SERNO = '000013A6DFC1' / Serial no (board) \n", - "HIERARCH ESO DET DEV2 BOARD4 TRANS = '00001216A91D' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV2 BOARD4 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV2 BOARD4 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV2 BOARD5 BCKPL = '0000106EDDFC' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV2 BOARD5 SERNO = '000013A6DAE7' / Serial no (board) \n", - "HIERARCH ESO DET DEV2 BOARD5 TRANS = '00001216DDB0' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV2 BOARD5 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV2 BOARD5 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV2 BOARD6 BCKPL = '0000106EDDFC' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV2 BOARD6 SERNO = '000013A6D5AD' / Serial no (board) \n", - "HIERARCH ESO DET DEV2 BOARD6 TRANS = '00001216DC4A' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV2 BOARD6 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV2 BOARD6 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV2 CHIPS = 6 / Number of chips in the mosaic \n", - "HIERARCH ESO DET DEV2 EXP RDTTIME = 47.232 / [s] Image readout time \n", - "HIERARCH ESO DET DEV2 EXP XFERTIM = 47.174 / [s] Image transfer time \n", - "HIERARCH ESO DET DEV2 ID = 'MUSE-NGC2' / Detector system Id \n", - "HIERARCH ESO DET DEV2 OUTPUTS = 24 / Number of outputs \n", - "HIERARCH ESO DET DEV2 REV = '3.1.1 ' / Revision \n", - "HIERARCH ESO DET DEV2 SHUT ID = 'eso-02 ' / Shutter unique identifier \n", - "HIERARCH ESO DET DEV2 SHUT TMCLOS = 0. / [s] Time taken to close shutter \n", - "HIERARCH ESO DET DEV2 SHUT TMOPEN = 0. / [s] Time taken to open shutter \n", - "HIERARCH ESO DET DEV2 SHUT TYPE = 'nostatus' / Shutter type \n", - "HIERARCH ESO DET DEV2 SOFW BASE = '306134 ' / Base software version \n", - "HIERARCH ESO DET DEV2 SOFW DETMOD = '340662 ' / Detector module revision \n", - "HIERARCH ESO DET DEV2 SOFW MODE = 'NORMAL ' / Software operational mode \n", - "HIERARCH ESO DET DEV2 SOFW OPT = '306134 ' / Optical software version \n", - "HIERARCH ESO DET DEV3 BOARD1 BCKPL = '000010779053' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV3 BOARD1 SERNO = '00001216CFCE' / Serial no (board) \n", - "HIERARCH ESO DET DEV3 BOARD1 TRANS = '00001216C0DE' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV3 BOARD1 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV3 BOARD1 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV3 BOARD2 BCKPL = '000010779053' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV3 BOARD2 SERNO = '000014587801' / Serial no (board) \n", - "HIERARCH ESO DET DEV3 BOARD2 TRANS = '00001216B302' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV3 BOARD2 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV3 BOARD2 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV3 BOARD3 BCKPL = '000010779053' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV3 BOARD3 SERNO = '000014588CA0' / Serial no (board) \n", - "HIERARCH ESO DET DEV3 BOARD3 TRANS = '00001216C3B2' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV3 BOARD3 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV3 BOARD3 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV3 BOARD4 BCKPL = '000010779053' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV3 BOARD4 SERNO = '000013A6C3DE' / Serial no (board) \n", - "HIERARCH ESO DET DEV3 BOARD4 TRANS = '00001216AA61' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV3 BOARD4 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV3 BOARD4 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV3 BOARD5 BCKPL = '000010779053' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV3 BOARD5 SERNO = '000013A6D093' / Serial no (board) \n", - "HIERARCH ESO DET DEV3 BOARD5 TRANS = '00001216CE5F' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV3 BOARD5 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV3 BOARD5 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV3 BOARD6 BCKPL = '000010779053' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV3 BOARD6 SERNO = '00001216B6A9' / Serial no (board) \n", - "HIERARCH ESO DET DEV3 BOARD6 TRANS = '000014588737' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV3 BOARD6 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV3 BOARD6 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV3 CHIPS = 6 / Number of chips in the mosaic \n", - "HIERARCH ESO DET DEV3 EXP RDTTIME = 47.232 / [s] Image readout time \n", - "HIERARCH ESO DET DEV3 EXP XFERTIM = 47.178 / [s] Image transfer time \n", - "HIERARCH ESO DET DEV3 ID = 'MUSE-NGC3' / Detector system Id \n", - "HIERARCH ESO DET DEV3 OUTPUTS = 24 / Number of outputs \n", - "HIERARCH ESO DET DEV3 REV = '3.1.1 ' / Revision \n", - "HIERARCH ESO DET DEV3 SHUT ID = 'eso-03 ' / Shutter unique identifier \n", - "HIERARCH ESO DET DEV3 SHUT TMCLOS = 0. / [s] Time taken to close shutter \n", - "HIERARCH ESO DET DEV3 SHUT TMOPEN = 0. / [s] Time taken to open shutter \n", - "HIERARCH ESO DET DEV3 SHUT TYPE = 'nostatus' / Shutter type \n", - "HIERARCH ESO DET DEV3 SOFW BASE = '306134 ' / Base software version \n", - "HIERARCH ESO DET DEV3 SOFW DETMOD = '340662 ' / Detector module revision \n", - "HIERARCH ESO DET DEV3 SOFW MODE = 'NORMAL ' / Software operational mode \n", - "HIERARCH ESO DET DEV3 SOFW OPT = '306134 ' / Optical software version \n", - "HIERARCH ESO DET DEV4 BOARD1 BCKPL = '0000106ED63C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV4 BOARD1 SERNO = '000011AA8715' / Serial no (board) \n", - "HIERARCH ESO DET DEV4 BOARD1 TRANS = '00001216DCAB' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV4 BOARD1 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV4 BOARD1 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV4 BOARD2 BCKPL = '0000106ED63C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV4 BOARD2 SERNO = '000013A6B7F1' / Serial no (board) \n", - "HIERARCH ESO DET DEV4 BOARD2 TRANS = '00001216B771' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV4 BOARD2 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV4 BOARD2 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV4 BOARD3 BCKPL = '0000106ED63C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV4 BOARD3 SERNO = '00001216DC74' / Serial no (board) \n", - "HIERARCH ESO DET DEV4 BOARD3 TRANS = '00001216DEEE' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV4 BOARD3 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV4 BOARD3 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV4 BOARD4 BCKPL = '0000106ED63C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV4 BOARD4 SERNO = '000013A6E15B' / Serial no (board) \n", - "HIERARCH ESO DET DEV4 BOARD4 TRANS = '00001216C953' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV4 BOARD4 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV4 BOARD4 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV4 BOARD5 BCKPL = '0000106ED63C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV4 BOARD5 SERNO = '000013A6C78E' / Serial no (board) \n", - "HIERARCH ESO DET DEV4 BOARD5 TRANS = '00001216C949' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV4 BOARD5 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV4 BOARD5 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV4 BOARD6 BCKPL = '0000106ED63C' / Serial no (backplane) \n", - "HIERARCH ESO DET DEV4 BOARD6 SERNO = '000013A6D756' / Serial no (board) \n", - "HIERARCH ESO DET DEV4 BOARD6 TRANS = '00001216CA4E' / Serial no (transition boar\n", - "HIERARCH ESO DET DEV4 BOARD6 TYPE = 'FEB ' / Type \n", - "HIERARCH ESO DET DEV4 BOARD6 VERSION = 1 / Version \n", - "HIERARCH ESO DET DEV4 CHIPS = 6 / Number of chips in the mosaic \n", - "HIERARCH ESO DET DEV4 EXP RDTTIME = 47.232 / [s] Image readout time \n", - "HIERARCH ESO DET DEV4 EXP XFERTIM = 47.176 / [s] Image transfer time \n", - "HIERARCH ESO DET DEV4 ID = 'MUSE-NGC4' / Detector system Id \n", - "HIERARCH ESO DET DEV4 OUTPUTS = 24 / Number of outputs \n", - "HIERARCH ESO DET DEV4 REV = '3.1.1 ' / Revision \n", - "HIERARCH ESO DET DEV4 SHUT ID = 'eso-04 ' / Shutter unique identifier \n", - "HIERARCH ESO DET DEV4 SHUT TMCLOS = 0. / [s] Time taken to close shutter \n", - "HIERARCH ESO DET DEV4 SHUT TMOPEN = 0. / [s] Time taken to open shutter \n", - "HIERARCH ESO DET DEV4 SHUT TYPE = 'nostatus' / Shutter type \n", - "HIERARCH ESO DET DEV4 SOFW BASE = '306134 ' / Base software version \n", - "HIERARCH ESO DET DEV4 SOFW DETMOD = '340662 ' / Detector module revision \n", - "HIERARCH ESO DET DEV4 SOFW MODE = 'NORMAL ' / Software operational mode \n", - "HIERARCH ESO DET DEV4 SOFW OPT = '306134 ' / Optical software version \n", - "HIERARCH ESO DET DID = 'ESO-VLT-DIC.NGCDCS,ESO-VLT-DIC.NGCCON' / Used di \n", - "HIERARCH ESO DET DIT1 = 1480. / [s] Actual subintegration time \n", - "HIERARCH ESO DET DKTM = 1480. / [s] Dark current time \n", - "HIERARCH ESO DET EXP NO = 118 / Unique exposure ID number \n", - "HIERARCH ESO DET EXP TYPE = 'Normal ' / Exposure type \n", - "HIERARCH ESO DET NAME = 'MUSE-NGCOPT' / Name of detector system \n", - "HIERARCH ESO DET NDIT = 1 / Number of Sub-Integrations \n", - "HIERARCH ESO DET OUTPUTS = 96 / Number of outputs \n", - "HIERARCH ESO DET READ CURID = 1 / Used readout mode id \n", - "HIERARCH ESO DET READ CURNAME = 'SCI1.0 ' / Used readout mode name \n", - "HIERARCH ESO DET UIT1 = 1480. / [s] User defined subintegration ti \n", - "HIERARCH ESO DET CON PWIPE = T / Periodic wipe \n", - "HIERARCH ESO DET OUT1 CONAD = 0.97 / [e-/ADU] Conversion ADUs to electr \n", - "HIERARCH ESO DET OUT1 GAIN = 1.0357 / [ADU/e-] Conversion electrons to A \n", - "HIERARCH ESO DET OUT1 ID = 'E ' / Output ID as from manufacturer \n", - "HIERARCH ESO DET OUT1 INDEX = 1 / Output index \n", - "HIERARCH ESO DET OUT1 NAME = 'NO1 ' / Description of output \n", - "HIERARCH ESO DET OUT1 NX = 2048 / Valid pixels along X \n", - "HIERARCH ESO DET OUT1 NY = 2056 / Valid pixels along Y \n", - "HIERARCH ESO DET OUT1 RON = 2.08 / [e-] Readout noise per output \n", - "HIERARCH ESO DET OUT1 X = 1 / X location of output \n", - "HIERARCH ESO DET OUT1 Y = 1 / Y location of output \n", - "HIERARCH ESO DET OUT2 CONAD = 0.96 / [e-/ADU] Conversion ADUs to electr \n", - "HIERARCH ESO DET OUT2 GAIN = 1.0426 / [ADU/e-] Conversion electrons to A \n", - "HIERARCH ESO DET OUT2 ID = 'F ' / Output ID as from manufacturer \n", - "HIERARCH ESO DET OUT2 INDEX = 2 / Output index \n", - "HIERARCH ESO DET OUT2 NAME = 'NO2 ' / Description of output \n", - "HIERARCH ESO DET OUT2 NX = 2048 / Valid pixels along X \n", - "HIERARCH ESO DET OUT2 NY = 2056 / Valid pixels along Y \n", - "HIERARCH ESO DET OUT2 RON = 1.99 / [e-] Readout noise per output \n", - "HIERARCH ESO DET OUT2 X = 4096 / X location of output \n", - "HIERARCH ESO DET OUT2 Y = 1 / Y location of output \n", - "HIERARCH ESO DET OUT3 CONAD = 0.91 / [e-/ADU] Conversion ADUs to electr \n", - "HIERARCH ESO DET OUT3 GAIN = 1.097 / [ADU/e-] Conversion electrons to A \n", - "HIERARCH ESO DET OUT3 ID = 'G ' / Output ID as from manufacturer \n", - "HIERARCH ESO DET OUT3 INDEX = 3 / Output index \n", - "HIERARCH ESO DET OUT3 NAME = 'NO3 ' / Description of output \n", - "HIERARCH ESO DET OUT3 NX = 2048 / Valid pixels along X \n", - "HIERARCH ESO DET OUT3 NY = 2056 / Valid pixels along Y \n", - "HIERARCH ESO DET OUT3 RON = 1.94 / [e-] Readout noise per output \n", - "HIERARCH ESO DET OUT3 X = 4096 / X location of output \n", - "HIERARCH ESO DET OUT3 Y = 4112 / Y location of output \n", - "HIERARCH ESO DET OUT4 CONAD = 0.92 / [e-/ADU] Conversion ADUs to electr \n", - "HIERARCH ESO DET OUT4 GAIN = 1.0842 / [ADU/e-] Conversion electrons to A \n", - "HIERARCH ESO DET OUT4 ID = 'H ' / Output ID as from manufacturer \n", - "HIERARCH ESO DET OUT4 INDEX = 4 / Output index \n", - "HIERARCH ESO DET OUT4 NAME = 'NO4 ' / Description of output \n", - "HIERARCH ESO DET OUT4 NX = 2048 / Valid pixels along X \n", - "HIERARCH ESO DET OUT4 NY = 2056 / Valid pixels along Y \n", - "HIERARCH ESO DET OUT4 RON = 2.33 / [e-] Readout noise per output \n", - "HIERARCH ESO DET OUT4 X = 1 / X location of output \n", - "HIERARCH ESO DET OUT4 Y = 4112 / Y location of output \n", - "HIERARCH ESO DET2 CHIP1 NX = 1024 / Physical active pixels in X \n", - "HIERARCH ESO DET2 CHIP1 NY = 1024 / Physical active pixels in Y \n", - "HIERARCH ESO DET2 CHIP1 X = 1 / X location in array \n", - "HIERARCH ESO DET2 CHIP1 Y = 1 / Y location in array \n", - "HIERARCH ESO DET2 SOFW MODE = 'NORMAL ' / Software operational mode \n", - "HIERARCH ESO DET2 TEMP MSG = 'Temperature monitoring system disabled' / Temperat\n", - "HIERARCH ESO DET2 TEMP1 DESC = 'Case ' / Temperature sensor description \n", - "HIERARCH ESO DET2 TEMP1 VAL = 283. / [K] Temperature sensor numeric value \n", - "HIERARCH ESO DET2 TEMP2 DESC = 'Chip ' / Temperature sensor description \n", - "HIERARCH ESO DET2 TEMP2 VAL = 243. / [K] Temperature sensor numeric value \n", - "HIERARCH ESO DET2 WIN1 BINX = 1 / Binning factor along X \n", - "HIERARCH ESO DET2 WIN1 BINY = 1 / Binning factor along Y \n", - "HIERARCH ESO DET2 WIN1 NX = 20 / # of pixels along X \n", - "HIERARCH ESO DET2 WIN1 NY = 20 / # of pixels along Y \n", - "HIERARCH ESO DET2 WIN1 ST = F / If T, window enabled \n", - "HIERARCH ESO DET2 WIN1 STRX = 1 / Lower left pixel in X \n", - "HIERARCH ESO DET2 WIN1 STRY = 1 / Lower left pixel in Y \n", - "HIERARCH ESO DET2 WIN1 UIT1 = 10. / user defined subintegration time \n", - "HIERARCH ESO DET2 WIN2 BINX = 1 / Binning factor along X \n", - "HIERARCH ESO DET2 WIN2 BINY = 1 / Binning factor along Y \n", - "HIERARCH ESO DET2 WIN2 NX = 20 / # of pixels along X \n", - "HIERARCH ESO DET2 WIN2 NY = 20 / # of pixels along Y \n", - "HIERARCH ESO DET2 WIN2 ST = F / If T, window enabled \n", - "HIERARCH ESO DET2 WIN2 STRX = 1 / Lower left pixel in X \n", - "HIERARCH ESO DET2 WIN2 STRY = 1 / Lower left pixel in Y \n", - "HIERARCH ESO DET CHIP DATE = '2012-10-12' / [YYYY-MM-DD] Date of installation \n", - "HIERARCH ESO DET CHIP ID = 'egeria ' / Detector chip identification \n", - "HIERARCH ESO DET CHIP INDEX = 6 / Chip index \n", - "HIERARCH ESO DET CHIP LIVE = T / Detector alive \n", - "HIERARCH ESO DET CHIP NAME = 'CHAN01 ' / Detector chip name \n", - "HIERARCH ESO DET CHIP NX = 4096 / Physical active pixels in X \n", - "HIERARCH ESO DET CHIP NY = 4112 / Physical active pixels in Y \n", - "HIERARCH ESO DET CHIP OVSCX = 50 / Physical overscan pixels in X \n", - "HIERARCH ESO DET CHIP OVSCY = 0 / Physical overscan pixels in Y \n", - "HIERARCH ESO DET CHIP PRSCX = 50 / Physical prescan pixels in X \n", - "HIERARCH ESO DET CHIP PRSCY = 0 / Physical prescan pixels in Y \n", - "HIERARCH ESO DET CHIP PSZX = 15. / [um] Size of pixel in X \n", - "HIERARCH ESO DET CHIP PSZY = 15. / [um] Size of pixel in Y \n", - "HIERARCH ESO DET CHIP RGAP = 0. / [deg] Angle of gap between chips \n", - "HIERARCH ESO DET CHIP X = 6 / X location in array \n", - "HIERARCH ESO DET CHIP XGAP = 0. / Gap after chips along x \n", - "HIERARCH ESO DET CHIP Y = 6 / Y location in array \n", - "HIERARCH ESO DET CHIP YGAP = 0. / Gap after chip along y \n", - "HIERARCH ESO PRO REC1 ID = 'muse_scibasic' / Pipeline recipe (unique) identifier\n", - "HIERARCH ESO PRO REC1 DRS ID = 'cpl-7.2.1' / Data Reduction System identifier \n", - "HIERARCH ESO PRO REC1 PIPE ID = 'muse/2.8.6' / Pipeline (unique) identifier \n", - "HIERARCH ESO PRO REC1 RAW1 NAME = 'MUSE.2022-06-24T08:46:05.083.fits' / File nam\n", - "HIERARCH ESO PRO REC1 RAW1 CATG = 'OBJECT ' / Category of raw frame \n", - "HIERARCH ESO PRO REC1 RAW2 NAME = 'MUSE.2022-06-24T08:38:52.310.fits' / File nam\n", - "HIERARCH ESO PRO REC1 RAW2 CATG = 'ILLUM ' / Category of raw frame \n", - "HIERARCH ESO PRO REC1 CAL1 NAME = 'MU_GEOT_210402A_geometry_table_wfm.fits' / Fi\n", - "HIERARCH ESO PRO REC1 CAL1 CATG = 'GEOMETRY_TABLE' / Category of calibration fra\n", - "HIERARCH ESO PRO REC1 CAL1 DATAMD5 = 'b475b34a6a697ecbd03691ba9212e1b6' / MD5 si\n", - "HIERARCH ESO PRO REC1 CAL2 NAME = 'MU_MBIA_220623A_WFM-AO-N_SCI1.0.fits' / File \n", - "HIERARCH ESO PRO REC1 CAL2 CATG = 'MASTER_BIAS' / Category of calibration frame \n", - "HIERARCH ESO PRO REC1 CAL2 DATAMD5 = '4ff3fa1938428ee697e9ebdce72a24b3' / MD5 si\n", - "HIERARCH ESO PRO REC1 CAL3 NAME = 'MU_MFLA_220623A_WFM-NOAO-N_Blue_SCI1.0.fits' \n", - "HIERARCH ESO PRO REC1 CAL3 CATG = 'MASTER_FLAT' / Category of calibration frame \n", - "HIERARCH ESO PRO REC1 CAL3 DATAMD5 = 'd67928428977973b14c938ce0af6b3bc' / MD5 si\n", - "HIERARCH ESO PRO REC1 CAL4 NAME = 'MU_PFTT_220623A_WFM-NOAO-N_Blue_SCI1.0.fits' \n", - "HIERARCH ESO PRO REC1 CAL4 CATG = 'TRACE_TABLE' / Category of calibration frame \n", - "HIERARCH ESO PRO REC1 CAL4 DATAMD5 = 'e5e34486ca0b32a04aba68b474fc483e' / MD5 si\n", - "HIERARCH ESO PRO REC1 CAL5 NAME = 'MU_MTWC_220628A_WFM-NOAO-N_Blue_SCI1.0.fits' \n", - "HIERARCH ESO PRO REC1 CAL5 CATG = 'TWILIGHT_CUBE' / Category of calibration fram\n", - "HIERARCH ESO PRO REC1 CAL5 DATAMD5 = 'bf0a882284d3d41d3bb8d8eebe6991cf' / MD5 si\n", - "HIERARCH ESO PRO REC1 CAL6 NAME = 'MU_PWCT_220623A_WFM-NOAO-N_Blue_SCI1.0.fits' \n", - "HIERARCH ESO PRO REC1 CAL6 CATG = 'WAVECAL_TABLE' / Category of calibration fram\n", - "HIERARCH ESO PRO REC1 CAL6 DATAMD5 = '1a54f54e8b50a6bd1c7f240aaaca6ced' / MD5 si\n", - "HIERARCH ESO PRO REC1 PARAM1 NAME = 'nifu ' / IFU to handle. If set to 0, all\n", - "HIERARCH ESO PRO REC1 PARAM1 VALUE = '-1 ' / Default: 0 \n", - "HIERARCH ESO PRO REC1 PARAM2 NAME = 'overscan' / If this is \"none\", stop when de\n", - "HIERARCH ESO PRO REC1 PARAM2 VALUE = 'vpoly ' / Default: 'vpoly' \n", - "HIERARCH ESO PRO REC1 PARAM3 NAME = 'ovscreject' / This influences how values ar\n", - "HIERARCH ESO PRO REC1 PARAM3 VALUE = 'dcr ' / Default: 'dcr' \n", - "HIERARCH ESO PRO REC1 PARAM4 NAME = 'ovscsigma' / If the deviation of mean overs\n", - "HIERARCH ESO PRO REC1 PARAM4 VALUE = '30 ' / Default: 30 \n", - "HIERARCH ESO PRO REC1 PARAM5 NAME = 'ovscignore' / The number of pixels of the o\n", - "HIERARCH ESO PRO REC1 PARAM5 VALUE = '3 ' / Default: 3 \n", - "HIERARCH ESO PRO REC1 PARAM6 NAME = 'crop ' / Automatically crop the output p\n", - "HIERARCH ESO PRO REC1 PARAM6 VALUE = 'true ' / Default: true \n", - "HIERARCH ESO PRO REC1 PARAM7 NAME = 'cr ' / Type of cosmic ray cleaning to \n", - "HIERARCH ESO PRO REC1 PARAM7 VALUE = 'none ' / Default: 'none' \n", - "HIERARCH ESO PRO REC1 PARAM8 NAME = 'xbox ' / Search box size in x. Only used\n", - "HIERARCH ESO PRO REC1 PARAM8 VALUE = '15 ' / Default: 15 \n", - "HIERARCH ESO PRO REC1 PARAM9 NAME = 'ybox ' / Search box size in y. Only used\n", - "HIERARCH ESO PRO REC1 PARAM9 VALUE = '40 ' / Default: 40 \n", - "HIERARCH ESO PRO REC1 PARAM10 NAME = 'passes ' / Maximum number of cleaning pas\n", - "HIERARCH ESO PRO REC1 PARAM10 VALUE = '2 ' / Default: 2 \n", - "HIERARCH ESO PRO REC1 PARAM11 NAME = 'thres ' / Threshold for detection gap in\n", - "HIERARCH ESO PRO REC1 PARAM11 VALUE = '5.8 ' / Default: 5.8 \n", - "HIERARCH ESO PRO REC1 PARAM12 NAME = 'combine ' / Type of combination to use. No\n", - "HIERARCH ESO PRO REC1 PARAM12 VALUE = 'none ' / Default: 'none' \n", - "HIERARCH ESO PRO REC1 PARAM13 NAME = 'nlow ' / Number of minimum pixels to re\n", - "HIERARCH ESO PRO REC1 PARAM13 VALUE = '1 ' / Default: 1 \n", - "HIERARCH ESO PRO REC1 PARAM14 NAME = 'nhigh ' / Number of maximum pixels to re\n", - "HIERARCH ESO PRO REC1 PARAM14 VALUE = '1 ' / Default: 1 \n", - "HIERARCH ESO PRO REC1 PARAM15 NAME = 'nkeep ' / Number of pixels to keep with \n", - "HIERARCH ESO PRO REC1 PARAM15 VALUE = '1 ' / Default: 1 \n", - "HIERARCH ESO PRO REC1 PARAM16 NAME = 'lsigma ' / Low sigma for pixel rejection \n", - "HIERARCH ESO PRO REC1 PARAM16 VALUE = '3 ' / Default: 3 \n", - "HIERARCH ESO PRO REC1 PARAM17 NAME = 'hsigma ' / High sigma for pixel rejection\n", - "HIERARCH ESO PRO REC1 PARAM17 VALUE = '3 ' / Default: 3 \n", - "HIERARCH ESO PRO REC1 PARAM18 NAME = 'scale ' / Scale the individual images to\n", - "HIERARCH ESO PRO REC1 PARAM18 VALUE = 'true ' / Default: true \n", - "HIERARCH ESO PRO REC1 PARAM19 NAME = 'saveimage' / Save the pre-processed CCD-ba\n", - "HIERARCH ESO PRO REC1 PARAM19 VALUE = 'true ' / Default: true \n", - "HIERARCH ESO PRO REC1 PARAM20 NAME = 'skylines' / List of wavelengths of sky emi\n", - "HIERARCH ESO PRO REC1 PARAM20 VALUE = '5577.339,6300.304' / Default: '5577.339,6\n", - "HIERARCH ESO PRO REC1 PARAM21 NAME = 'skyhalfwidth' / Half-width of the extracti\n", - "HIERARCH ESO PRO REC1 PARAM21 VALUE = '5 ' / Default: 5 \n", - "HIERARCH ESO PRO REC1 PARAM22 NAME = 'skybinsize' / Size of the bins (in Angstro\n", - "HIERARCH ESO PRO REC1 PARAM22 VALUE = '0.1 ' / Default: 0.1 \n", - "HIERARCH ESO PRO REC1 PARAM23 NAME = 'skyreject' / Sigma clipping parameters for\n", - "HIERARCH ESO PRO REC1 PARAM23 VALUE = '15.,15.,1' / Default: '15.,15.,1' \n", - "HIERARCH ESO PRO REC1 PARAM24 NAME = 'resample' / Resample the input science dat\n", - "HIERARCH ESO PRO REC1 PARAM24 VALUE = 'false ' / Default: false \n", - "HIERARCH ESO PRO REC1 PARAM25 NAME = 'dlambda ' / Wavelength step (in Angstrom p\n", - "HIERARCH ESO PRO REC1 PARAM25 VALUE = '1.25 ' / Default: 1.25 \n", - "HIERARCH ESO PRO REC1 PARAM26 NAME = 'merge ' / Merge output products from dif\n", - "HIERARCH ESO PRO REC1 PARAM26 VALUE = 'false ' / Default: false \n", - "HIERARCH ESO PRO REC2 ID = 'muse_scipost' / Pipeline recipe (unique) identifier \n", - "HIERARCH ESO PRO REC2 DRS ID = 'cpl-7.2.1' / Data Reduction System identifier \n", - "HIERARCH ESO PRO REC2 PIPE ID = 'muse/2.8.6' / Pipeline (unique) identifier \n", - "HIERARCH ESO PRO REC2 RAW1 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-01.fits' \n", - "HIERARCH ESO PRO REC2 RAW1 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW2 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-02.fits' \n", - "HIERARCH ESO PRO REC2 RAW2 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW3 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-03.fits' \n", - "HIERARCH ESO PRO REC2 RAW3 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW4 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-04.fits' \n", - "HIERARCH ESO PRO REC2 RAW4 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW5 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-05.fits' \n", - "HIERARCH ESO PRO REC2 RAW5 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW6 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-06.fits' \n", - "HIERARCH ESO PRO REC2 RAW6 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW7 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-07.fits' \n", - "HIERARCH ESO PRO REC2 RAW7 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW8 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-08.fits' \n", - "HIERARCH ESO PRO REC2 RAW8 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW9 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-09.fits' \n", - "HIERARCH ESO PRO REC2 RAW9 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW10 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-10.fits'\n", - "HIERARCH ESO PRO REC2 RAW10 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW11 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-11.fits'\n", - "HIERARCH ESO PRO REC2 RAW11 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW12 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-12.fits'\n", - "HIERARCH ESO PRO REC2 RAW12 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW13 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-13.fits'\n", - "HIERARCH ESO PRO REC2 RAW13 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW14 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-14.fits'\n", - "HIERARCH ESO PRO REC2 RAW14 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW15 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-15.fits'\n", - "HIERARCH ESO PRO REC2 RAW15 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW16 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-16.fits'\n", - "HIERARCH ESO PRO REC2 RAW16 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW17 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-17.fits'\n", - "HIERARCH ESO PRO REC2 RAW17 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW18 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-18.fits'\n", - "HIERARCH ESO PRO REC2 RAW18 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW19 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-19.fits'\n", - "HIERARCH ESO PRO REC2 RAW19 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW20 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-20.fits'\n", - "HIERARCH ESO PRO REC2 RAW20 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW21 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-21.fits'\n", - "HIERARCH ESO PRO REC2 RAW21 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW22 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-22.fits'\n", - "HIERARCH ESO PRO REC2 RAW22 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW23 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-23.fits'\n", - "HIERARCH ESO PRO REC2 RAW23 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 RAW24 NAME = 'r.MUSE.2022-06-24T08:46:05.083_0001-24.fits'\n", - "HIERARCH ESO PRO REC2 RAW24 CATG = 'PIXTABLE_OBJECT' / Category of raw frame \n", - "HIERARCH ESO PRO REC2 CAL1 NAME = 'MU_GASW_210402B_astrom_wcs_wfm.fits' / File n\n", - "HIERARCH ESO PRO REC2 CAL1 CATG = 'ASTROMETRY_WCS' / Category of calibration fra\n", - "HIERARCH ESO PRO REC2 CAL1 DATAMD5 = '8b58beecf921e7b72ea17360152bae0a' / MD5 si\n", - "HIERARCH ESO PRO REC2 CAL2 NAME = 'MU_GEXT_140101A_extinct_table.fits' / File na\n", - "HIERARCH ESO PRO REC2 CAL2 CATG = 'EXTINCT_TABLE' / Category of calibration fram\n", - "HIERARCH ESO PRO REC2 CAL3 NAME = 'MU_GLSP_170422A_lsf_profile_slow_wfm-n.fits' \n", - "HIERARCH ESO PRO REC2 CAL3 CATG = 'LSF_PROFILE' / Category of calibration frame \n", - "HIERARCH ESO PRO REC2 CAL3 DATAMD5 = '182cefd08acf03bc6eb5d2c6d8a1c54a' / MD5 si\n", - "HIERARCH ESO PRO REC2 CAL4 NAME = 'MU_GSKL_140101A_sky_lines.fits' / File name o\n", - "HIERARCH ESO PRO REC2 CAL4 CATG = 'SKY_LINES' / Category of calibration frame \n", - "HIERARCH ESO PRO REC2 CAL5 NAME = 'MU_MSDR_220623A_WFM-NOAO-N_Blue_SCI1.0.fits' \n", - "HIERARCH ESO PRO REC2 CAL5 CATG = 'STD_RESPONSE' / Category of calibration frame\n", - "HIERARCH ESO PRO REC2 CAL5 DATAMD5 = '9f32a9ad602f5f367443b878cce733c0' / MD5 si\n", - "HIERARCH ESO PRO REC2 CAL6 NAME = 'MU_MSDT_220623A_WFM-NOAO-N_Blue_SCI1.0.fits' \n", - "HIERARCH ESO PRO REC2 CAL6 CATG = 'STD_TELLURIC' / Category of calibration frame\n", - "HIERARCH ESO PRO REC2 CAL6 DATAMD5 = 'eb041cf903240a0ca072fc8dbfed9328' / MD5 si\n", - "HIERARCH ESO PRO REC2 PARAM1 NAME = 'save ' / Select output product(s) to sav\n", - "HIERARCH ESO PRO REC2 PARAM1 VALUE = 'individual,stacked,cube,skymodel' / Defaul\n", - "HIERARCH ESO PRO REC2 PARAM2 NAME = 'resample' / The resampling technique to use\n", - "HIERARCH ESO PRO REC2 PARAM2 VALUE = 'drizzle ' / Default: 'drizzle' \n", - "HIERARCH ESO PRO REC2 PARAM3 NAME = 'dx ' / Horizontal step size for resamp\n", - "HIERARCH ESO PRO REC2 PARAM3 VALUE = '0 ' / Default: 0 \n", - "HIERARCH ESO PRO REC2 PARAM4 NAME = 'dy ' / Vertical step size for resampli\n", - "HIERARCH ESO PRO REC2 PARAM4 VALUE = '0 ' / Default: 0 \n", - "HIERARCH ESO PRO REC2 PARAM5 NAME = 'dlambda ' / Wavelength step size (in Angstr\n", - "HIERARCH ESO PRO REC2 PARAM5 VALUE = '0 ' / Default: 0 \n", - "HIERARCH ESO PRO REC2 PARAM6 NAME = 'crtype ' / Type of statistics used for det\n", - "HIERARCH ESO PRO REC2 PARAM6 VALUE = 'median ' / Default: 'median' \n", - "HIERARCH ESO PRO REC2 PARAM7 NAME = 'crsigma ' / Sigma rejection factor to use f\n", - "HIERARCH ESO PRO REC2 PARAM7 VALUE = '15 ' / Default: 15 \n", - "HIERARCH ESO PRO REC2 PARAM8 NAME = 'rc ' / Critical radius for the \"renka\"\n", - "HIERARCH ESO PRO REC2 PARAM8 VALUE = '1.25 ' / Default: 1.25 \n", - "HIERARCH ESO PRO REC2 PARAM9 NAME = 'pixfrac ' / Pixel down-scaling factor for t\n", - "HIERARCH ESO PRO REC2 PARAM9 VALUE = '0.8,0.8 ' / Default: '0.8,0.8' \n", - "HIERARCH ESO PRO REC2 PARAM10 NAME = 'ld ' / Number of adjacent pixels to t\n", - "HIERARCH ESO PRO REC2 PARAM10 VALUE = '1 ' / Default: 1 \n", - "HIERARCH ESO PRO REC2 PARAM11 NAME = 'format ' / Type of output file format, \"C\n", - "HIERARCH ESO PRO REC2 PARAM11 VALUE = 'sdpCube ' / Default: 'Cube' \n", - "HIERARCH ESO PRO REC2 PARAM12 NAME = 'weight ' / Type of weighting scheme to us\n", - "HIERARCH ESO PRO REC2 PARAM12 VALUE = 'exptime ' / Default: 'exptime' \n", - "HIERARCH ESO PRO REC2 PARAM13 NAME = 'filter ' / The filter name(s) to be used \n", - "HIERARCH ESO PRO REC2 PARAM13 VALUE = 'white ' / Default: 'white' \n", - "HIERARCH ESO PRO REC2 PARAM14 NAME = 'autocalib' / The type of autocalibration t\n", - "HIERARCH ESO PRO REC2 PARAM14 VALUE = 'none ' / Default: 'none' \n", - "HIERARCH ESO PRO REC2 PARAM15 NAME = 'raman_width' / Wavelength range around Ram\n", - "HIERARCH ESO PRO REC2 PARAM15 VALUE = '20 ' / Default: 20 \n", - "HIERARCH ESO PRO REC2 PARAM16 NAME = 'skymethod' / The method used to subtract t\n", - "HIERARCH ESO PRO REC2 PARAM16 VALUE = 'model ' / Default: 'model' \n", - "HIERARCH ESO PRO REC2 PARAM17 NAME = 'lambdamin' / Cut off the data below this w\n", - "HIERARCH ESO PRO REC2 PARAM17 VALUE = '4000 ' / Default: 4000 \n", - "HIERARCH ESO PRO REC2 PARAM18 NAME = 'lambdamax' / Cut off the data above this w\n", - "HIERARCH ESO PRO REC2 PARAM18 VALUE = '10000 ' / Default: 10000 \n", - "HIERARCH ESO PRO REC2 PARAM19 NAME = 'lambdaref' / Reference wavelength used for\n", - "HIERARCH ESO PRO REC2 PARAM19 VALUE = '7000 ' / Default: 7000 \n", - "HIERARCH ESO PRO REC2 PARAM20 NAME = 'darcheck' / Carry out a check of the theor\n", - "HIERARCH ESO PRO REC2 PARAM20 VALUE = 'none ' / Default: 'none' \n", - "HIERARCH ESO PRO REC2 PARAM21 NAME = 'skymodel_fraction' / Fraction of the image\n", - "HIERARCH ESO PRO REC2 PARAM21 VALUE = '0.2 ' / Default: 0.1 \n", - "HIERARCH ESO PRO REC2 PARAM22 NAME = 'skymodel_ignore' / Fraction of the image t\n", - "HIERARCH ESO PRO REC2 PARAM22 VALUE = '0.05 ' / Default: 0.05 \n", - "HIERARCH ESO PRO REC2 PARAM23 NAME = 'skymodel_sampling' / Spectral sampling of \n", - "HIERARCH ESO PRO REC2 PARAM23 VALUE = '0.3125 ' / Default: 0.3125 \n", - "HIERARCH ESO PRO REC2 PARAM24 NAME = 'skymodel_csampling' / Spectral sampling of\n", - "HIERARCH ESO PRO REC2 PARAM24 VALUE = '0.3125 ' / Default: 0.3125 \n", - "HIERARCH ESO PRO REC2 PARAM25 NAME = 'sky_crsigma' / Sigma level clipping for cu\n", - "HIERARCH ESO PRO REC2 PARAM25 VALUE = '15.,15. ' / Default: '15.,15.' \n", - "HIERARCH ESO PRO REC2 PARAM26 NAME = 'rvcorr ' / Correct the radial velocity of\n", - "HIERARCH ESO PRO REC2 PARAM26 VALUE = 'bary ' / Default: 'bary' \n", - "HIERARCH ESO PRO REC2 PARAM27 NAME = 'astrometry' / If false, skip any astrometr\n", - "HIERARCH ESO PRO REC2 PARAM27 VALUE = 'true ' / Default: true \n", - "HIERARCH ESO PRO ANCESTOR = 'MUSE.2022-06-24T08:46:05.083.fits' \n", - "HIERARCH ESO PRO DID = 'PRO-1.16' / Data dictionary for PRO \n", - "HIERARCH ESO PRO CATG = 'DATACUBE_COMBINED' / modified \n", - "HIERARCH ESO PRO TYPE = 'REDUCED ' / Product type \n", - "HIERARCH ESO PRO TECH = 'IFU ' / Observation technique \n", - "HIERARCH ESO PRO SCIENCE = T / Scientific product if T \n", - "HIERARCH ESO PRO REC3 ID = 'muse_exp_combine' / Pipeline recipe (unique) identif\n", - "HIERARCH ESO PRO REC3 DRS ID = 'cpl-7.2.1' / Data Reduction System identifier \n", - "HIERARCH ESO PRO REC3 PIPE ID = 'muse/2.8.6' / Pipeline (unique) identifier \n", - "HIERARCH ESO PRO REC3 RAW1 NAME = 'r.MUSE.2022-06-24T08:46:05.083_pst_0002.fits'\n", - "HIERARCH ESO PRO REC3 RAW1 CATG = 'PIXTABLE_REDUCED' / Category of raw frame \n", - "HIERARCH ESO PRO REC3 RAW2 NAME = 'r.MUSE.2022-06-24T09:12:43.926_pst_0002.fits'\n", - "HIERARCH ESO PRO REC3 RAW2 CATG = 'PIXTABLE_REDUCED' / Category of raw frame \n", - "HIERARCH ESO PRO DATANCOM = 2 / Number of combined frames \n", - "HIERARCH ESO PRO REC3 CAL1 NAME = 'r.MUSE.2022-06-24T08:46:05.083_tal_0000.fits'\n", - "HIERARCH ESO PRO REC3 CAL1 CATG = 'OFFSET_LIST' / Category of calibration frame \n", - "HIERARCH ESO PRO REC3 CAL1 DATAMD5 = 'Not computed' / MD5 signature of calib fra\n", - "HIERARCH ESO PRO REC3 PARAM1 NAME = 'save ' / Select output product(s) to sav\n", - "HIERARCH ESO PRO REC3 PARAM1 VALUE = 'cube,combined' / Default: 'cube' \n", - "HIERARCH ESO PRO REC3 PARAM2 NAME = 'resample' / The resampling technique to use\n", - "HIERARCH ESO PRO REC3 PARAM2 VALUE = 'drizzle ' / Default: 'drizzle' \n", - "HIERARCH ESO PRO REC3 PARAM3 NAME = 'dx ' / Horizontal step size for resamp\n", - "HIERARCH ESO PRO REC3 PARAM3 VALUE = '0 ' / Default: 0 \n", - "HIERARCH ESO PRO REC3 PARAM4 NAME = 'dy ' / Vertical step size for resampli\n", - "HIERARCH ESO PRO REC3 PARAM4 VALUE = '0 ' / Default: 0 \n", - "HIERARCH ESO PRO REC3 PARAM5 NAME = 'dlambda ' / Wavelength step size (in Angstr\n", - "HIERARCH ESO PRO REC3 PARAM5 VALUE = '0 ' / Default: 0 \n", - "HIERARCH ESO PRO REC3 PARAM6 NAME = 'crtype ' / Type of statistics used for det\n", - "HIERARCH ESO PRO REC3 PARAM6 VALUE = 'median ' / Default: 'median' \n", - "HIERARCH ESO PRO REC3 PARAM7 NAME = 'crsigma ' / Sigma rejection factor to use f\n", - "HIERARCH ESO PRO REC3 PARAM7 VALUE = '10 ' / Default: 10 \n", - "HIERARCH ESO PRO REC3 PARAM8 NAME = 'rc ' / Critical radius for the \"renka\"\n", - "HIERARCH ESO PRO REC3 PARAM8 VALUE = '1.25 ' / Default: 1.25 \n", - "HIERARCH ESO PRO REC3 PARAM9 NAME = 'pixfrac ' / Pixel down-scaling factor for t\n", - "HIERARCH ESO PRO REC3 PARAM9 VALUE = '0.6,0.6 ' / Default: '0.6,0.6' \n", - "HIERARCH ESO PRO REC3 PARAM10 NAME = 'ld ' / Number of adjacent pixels to t\n", - "HIERARCH ESO PRO REC3 PARAM10 VALUE = '1 ' / Default: 1 \n", - "HIERARCH ESO PRO REC3 PARAM11 NAME = 'format ' / Type of output file format, \"C\n", - "HIERARCH ESO PRO REC3 PARAM11 VALUE = 'sdpCube ' / Default: 'Cube' \n", - "HIERARCH ESO PRO REC3 PARAM12 NAME = 'weight ' / Type of weighting scheme to us\n", - "HIERARCH ESO PRO REC3 PARAM12 VALUE = 'exptime ' / Default: 'exptime' \n", - "HIERARCH ESO PRO REC3 PARAM13 NAME = 'filter ' / The filter name(s) to be used \n", - "HIERARCH ESO PRO REC3 PARAM13 VALUE = 'white ' / Default: 'white' \n", - "HIERARCH ESO PRO REC3 PARAM14 NAME = 'lambdamin' / Cut off the data below this w\n", - "HIERARCH ESO PRO REC3 PARAM14 VALUE = '4000 ' / Default: 4000 \n", - "HIERARCH ESO PRO REC3 PARAM15 NAME = 'lambdamax' / Cut off the data above this w\n", - "HIERARCH ESO PRO REC3 PARAM15 VALUE = '10000 ' / Default: 10000 \n", - "HIERARCH ESO ADA ABSROT END = -0.08822 / [deg] Abs rot angle at exp end \n", - "HIERARCH ESO ADA ABSROT PPOS = 'POS ' / sign of probe position \n", - "HIERARCH ESO ADA ABSROT START = 3.35131 / [deg] Abs rot angle at exp start \n", - "HIERARCH ESO ADA GUID DEC = -54.49912 / [deg] -54:29:56.8 Guide star DEC J2000 \n", - "HIERARCH ESO ADA GUID RA = 25.63266 / [deg] 01:42:31.8 Guide star RA J2000 \n", - "HIERARCH ESO ADA GUID STATUS = 'ON ' / Status of autoguider \n", - "HIERARCH ESO ADA POSANG = -208.53412 / [deg] Position angle at start \n", - "HIERARCH ESO ADA POSANG END = -202.287 / [deg] Position angle at exposure end \n", - "HIERARCH ESO ADA PUPILPOS = 45.01077 / [deg] Pupil position angle at exposure st\n", - "HIERARCH ESO AOS HO LOOP ST = F / High Order loop status \n", - "HIERARCH ESO AOS HO LOOP SUBSTATE = 41 / High Order loop substate \n", - "HIERARCH ESO AOS IR LOOP ST = F / IRLOS loop status \n", - "HIERARCH ESO AOS IR LOOP SUBSTATE = 41 / IRLOS loop substate \n", - "HIERARCH ESO AOS JIT LOOP ST = F / Jitter loop status \n", - "HIERARCH ESO AOS JIT LOOP SUBSTATE = 41 / Jitter loop substate \n", - "HIERARCH ESO AOS NGS ALPHA = 174541.547 / [hms] Alpha coordinate for the NGS \n", - "HIERARCH ESO AOS NGS DELTA = -460431.568 / [dms] Delta coordinate for the NGS \n", - "HIERARCH ESO AOS TT LOOP ST = F / Tip-tilt loop status \n", - "HIERARCH ESO AOS TT LOOP SUBSTATE = 0 / Tip-tilt loop substate \n", - "HIERARCH ESO OCS DET1 IMGNAME = 'MUSE_WFM-NOAO_OBS' / Data File Name. \n", - "HIERARCH ESO OCS IPS PIXSCALE = 0.2 / [arcsec/pixel] Pixel scale \n", - "HIERARCH ESO OCS SGS AG FWHMX AVG = 1.145 / [arcsec] AG FWHM X mean value \n", - "HIERARCH ESO OCS SGS AG FWHMX MAX = 1.361 / [arcsec] AG FWHM X maximum value \n", - "HIERARCH ESO OCS SGS AG FWHMX MED = 1.137 / [arcsec] AG FWHM X median value \n", - "HIERARCH ESO OCS SGS AG FWHMX MIN = 0.954 / [arcsec] AG FWHM X minimum value \n", - "HIERARCH ESO OCS SGS AG FWHMX RMS = 0.085 / [arcsec] AG FWHM X RMS value \n", - "HIERARCH ESO OCS SGS AG FWHMY AVG = 1.178 / [arcsec] AG FWHM Y mean value \n", - "HIERARCH ESO OCS SGS AG FWHMY MAX = 1.498 / [arcsec] AG FWHM Y maximum value \n", - "HIERARCH ESO OCS SGS AG FWHMY MED = 1.173 / [arcsec] AG FWHM Y median value \n", - "HIERARCH ESO OCS SGS AG FWHMY MIN = 0.967 / [arcsec] AG FWHM Y minimum value \n", - "HIERARCH ESO OCS SGS AG FWHMY RMS = 0.094 / [arcsec] AG FWHM Y RMS value \n", - "HIERARCH ESO OCS SGS ALGO NAME = 'CORRELATOR' / Centering method \n", - "HIERARCH ESO OCS SGS ALGO WIN SCALE = 6. / Factor for window size \n", - "HIERARCH ESO OCS SGS ALGO WIN SIZE = 60 / [pix] Window size \n", - "HIERARCH ESO OCS SGS ASM GL900 AVG = 0.74 / ASM ground layer ratio @ 900m mean \n", - "HIERARCH ESO OCS SGS ASM GL900 MAX = 0.797 / ASM ground layer ratio @ 900m maxim\n", - "HIERARCH ESO OCS SGS ASM GL900 MED = 0.71 / ASM ground layer ratio @ 900m media \n", - "HIERARCH ESO OCS SGS ASM GL900 MIN = 0.69 / ASM ground layer ratio @ 900m minim \n", - "HIERARCH ESO OCS SGS ASM GL900 RMS = 0.037 / ASM ground layer ratio @ 900m RMS v\n", - "HIERARCH ESO OCS SGS FLUX AVG = 1049000. / [ADU] SGS flux mean value \n", - "HIERARCH ESO OCS SGS FLUX MAX = 1148000. / [ADU] SGS flux maximum value \n", - "HIERARCH ESO OCS SGS FLUX MED = 1070000. / [ADU] SGS flux median value \n", - "HIERARCH ESO OCS SGS FLUX MIN = 874700. / [ADU] SGS flux minimum value \n", - "HIERARCH ESO OCS SGS FLUX RMS = 63860. / [ADU] SGS flux RMS value \n", - "HIERARCH ESO OCS SGS FLUX RMSPRC = 6. / [%] SGS flux RMS percentage value \n", - "HIERARCH ESO OCS SGS FWHM AVG = 1.086 / [arcsec] SGS FWHM mean value \n", - "HIERARCH ESO OCS SGS FWHM MAX = 1.472 / [arcsec] SGS FWHM maximum value \n", - "HIERARCH ESO OCS SGS FWHM MED = 1.058 / [arcsec] SGS FWHM median value \n", - "HIERARCH ESO OCS SGS FWHM MIN = 0.88 / [arcsec] SGS FWHM minimum value \n", - "HIERARCH ESO OCS SGS FWHM RMS = 0.12 / [arcsec] SGS FWHM RMS value \n", - "HIERARCH ESO OCS SGS LOOP CLOSED PRCTG = 100. / SGS closed loop percentage \n", - "HIERARCH ESO OCS SGS LOOP GAIN = 0.95 / SGS loop gain \n", - "HIERARCH ESO OCS SGS LOOP MODE = 2 / SGS loop mode \n", - "HIERARCH ESO OCS SGS LOOP MODENAME = 'GUIDING ' / SGS loop mode name \n", - "HIERARCH ESO OCS SGS LOOP PERIOD = 126 / [s] SGS loop period \n", - "HIERARCH ESO OCS SGS LOOP ST = T / SGS loop status \n", - "HIERARCH ESO OCS SGS NOBJ = 2 / Nb of objects for slow-guiding \n", - "HIERARCH ESO OCS SGS OBJ1 FLUX = 793000. / [ADU] Flux of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ1 REJECTED = F / Rejected flag of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ1 USED PRCTG = 100. / % of time SGS object #i has been \n", - "HIERARCH ESO OCS SGS OBJ1 X = 566.1 / X-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ1 Y = 98.7 / Y-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ10 FLUX = 0. / [ADU] Flux of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ10 REJECTED = F / Rejected flag of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ10 USED PRCTG = 0. / % of time SGS object #i has been u \n", - "HIERARCH ESO OCS SGS OBJ10 X = 0. / X-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ10 Y = 0. / Y-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ2 FLUX = 318800. / [ADU] Flux of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ2 REJECTED = F / Rejected flag of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ2 USED PRCTG = 100. / % of time SGS object #i has been \n", - "HIERARCH ESO OCS SGS OBJ2 X = 856.2 / X-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ2 Y = 463. / Y-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ3 FLUX = 0. / [ADU] Flux of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ3 REJECTED = F / Rejected flag of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ3 USED PRCTG = 0. / % of time SGS object #i has been us \n", - "HIERARCH ESO OCS SGS OBJ3 X = 0. / X-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ3 Y = 0. / Y-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ4 FLUX = 0. / [ADU] Flux of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ4 REJECTED = F / Rejected flag of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ4 USED PRCTG = 0. / % of time SGS object #i has been us \n", - "HIERARCH ESO OCS SGS OBJ4 X = 0. / X-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ4 Y = 0. / Y-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ5 FLUX = 0. / [ADU] Flux of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ5 REJECTED = F / Rejected flag of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ5 USED PRCTG = 0. / % of time SGS object #i has been us \n", - "HIERARCH ESO OCS SGS OBJ5 X = 0. / X-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ5 Y = 0. / Y-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ6 FLUX = 0. / [ADU] Flux of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ6 REJECTED = F / Rejected flag of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ6 USED PRCTG = 0. / % of time SGS object #i has been us \n", - "HIERARCH ESO OCS SGS OBJ6 X = 0. / X-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ6 Y = 0. / Y-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ7 FLUX = 0. / [ADU] Flux of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ7 REJECTED = F / Rejected flag of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ7 USED PRCTG = 0. / % of time SGS object #i has been us \n", - "HIERARCH ESO OCS SGS OBJ7 X = 0. / X-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ7 Y = 0. / Y-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ8 FLUX = 0. / [ADU] Flux of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ8 REJECTED = F / Rejected flag of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ8 USED PRCTG = 0. / % of time SGS object #i has been us \n", - "HIERARCH ESO OCS SGS OBJ8 X = 0. / X-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ8 Y = 0. / Y-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ9 FLUX = 0. / [ADU] Flux of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ9 REJECTED = F / Rejected flag of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ9 USED PRCTG = 0. / % of time SGS object #i has been us \n", - "HIERARCH ESO OCS SGS OBJ9 X = 0. / X-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OBJ9 Y = 0. / Y-position of the SGS object #i \n", - "HIERARCH ESO OCS SGS OFFSET DECAVG = 0.002 / [arcsec] SGS delta offset mean valu\n", - "HIERARCH ESO OCS SGS OFFSET DECMAX = 0.015 / [arcsec] SGS delta offset maximum v\n", - "HIERARCH ESO OCS SGS OFFSET DECMED = 0. / [arcsec] SGS delta offset median va \n", - "HIERARCH ESO OCS SGS OFFSET DECMIN = -0.02 / [arcsec] SGS delta offset minimum \n", - "HIERARCH ESO OCS SGS OFFSET DECRMS = 0.009 / [arcsec] SGS delta offset RMS value\n", - "HIERARCH ESO OCS SGS OFFSET DECSUM = 0.025 / [arcsec] SGS cumulated delta offset\n", - "HIERARCH ESO OCS SGS OFFSET ENABLED = T / SGS offsetting status \n", - "HIERARCH ESO OCS SGS OFFSET RAAVG = -0.009 / [arcsec] SGS alpha offset mean valu\n", - "HIERARCH ESO OCS SGS OFFSET RAMAX = 0. / [arcsec] SGS alpha offset maximum va \n", - "HIERARCH ESO OCS SGS OFFSET RAMED = 0. / [arcsec] SGS alpha offset median val \n", - "HIERARCH ESO OCS SGS OFFSET RAMIN = -0.027 / [arcsec] SGS alpha offset minimum v\n", - "HIERARCH ESO OCS SGS OFFSET RARMS = 0.011 / [arcsec] SGS alpha offset RMS value \n", - "HIERARCH ESO OCS SGS OFFSET RASUM = -0.102 / [arcsec] SGS cumulated alpha offset\n", - "HIERARCH ESO OCS SGS OFFSET THRMAX = 0.4 / [arcsec] Alpha/Delta max offset thr \n", - "HIERARCH ESO OCS SGS OFFSET THRMIN = 0.02 / [arcsec] Alpha/Delta min offset thr \n", - "HIERARCH ESO OCS SGS PIXSCALE X = 0.093 / [arcsec/pix] X pixel scale of SGS \n", - "HIERARCH ESO OCS SGS PIXSCALE Y = 0.0895 / [arcsec/pix] Y pixel scale of SGS \n", - "HIERARCH ESO OCS SGS REF NBIMG = 1 / Number of images for reference image \n", - "HIERARCH ESO OCS SGS REF SAVE = 'MUSE_SGS_REF_START_POS.fits' / SGS reference fi\n", - "HIERARCH ESO OCS SGS REJECT PRCTG = 0. / Image rejection ratio \n", - "HIERARCH ESO OCS TEL ACCESS = 'NORMAL ' / Sub-system access mode. \n", - "HIERARCH ESO SEQ OFFSET COORDS = 'SKY ' / Offset coordinate type \n", - "HIERARCH ESO SEQ OFFSET CUM ALPHA = 0. / [arcsec] Cumulative alpha offset \n", - "HIERARCH ESO SEQ OFFSET CUM DELTA = 0. / [arcsec] Cumulative delta offset \n", - "HIERARCH ESO SEQ OFFSET REL ALPHA = 0. / [arcsec] Relative alpha offset \n", - "HIERARCH ESO SEQ OFFSET REL DELTA = 0. / [arcsec] Relative delta offset \n", - "HIERARCH ESO QC EXPCOMB LAMBDA = 7050.238 / [Angstrom] Wavelength of plane in co\n", - "HIERARCH ESO QC EXPCOMB NDET = 1 / Number of detected sources in combined cube. \n", - "HIERARCH ESO QC EXPCOMB POS1 X = 62. / [pix] Position of source k in x-direction\n", - "HIERARCH ESO QC EXPCOMB POS1 Y = 82. / [pix] Position of source k in y-direction\n", - "HIERARCH ESO QC EXPCOMB FWHM1 X = 1.095375 / [arcsec] FWHM of source k in x-dire\n", - "HIERARCH ESO QC EXPCOMB FWHM1 Y = 0.9143061 / [arcsec] FWHM of source k in y-dir\n", - "HIERARCH ESO QC EXPCOMB FWHM NVALID = 1 / Number of detected sources with valid \n", - "HIERARCH ESO QC EXPCOMB FWHM MEDIAN = 0. / [arcsec] Median FWHM of all sources w\n", - "HIERARCH ESO QC EXPCOMB FWHM MAD = 0. / [arcsec] Median absolute deviation of th\n", - "HIERARCH ESO DRS MUSE OFFSET1 DRA = 0. / [deg] (= 0.000000 arcsec) RA offset app\n", - "HIERARCH ESO DRS MUSE OFFSET1 DDEC = 0. / [deg] (= 0.000000 arcsec) DEC offset a\n", - "HIERARCH ESO DRS MUSE OFFSET1 DATE-OBS = '2022-06-24T08:46:05.082' / offset 1 ap\n", - "HIERARCH ESO DRS MUSE OFFSET2 DRA = 9.83664008913365E-06 / [deg] (= 0.035412 arc\n", - "HIERARCH ESO DRS MUSE OFFSET2 DDEC = 5.17123623851035E-05 / [deg] (= 0.186165 ar\n", - "HIERARCH ESO DRS MUSE OFFSET2 DATE-OBS = '2022-06-24T09:12:43.926' / offset 2 ap\n", - "HIERARCH ESO DRS MUSE FLUX FFCORR = T / Data was flat-field spectrum corrected \n", - "ASSON2 = 'r.MUSE.2022-06-24T08:46:05.083_tpl.log' \n", - "ASSOC2 = 'ANCILLARY.README' \n", - "ASSOM2 = '9d90cc64f5a48840fe0bbcc5584bc526' \n", - "ASSON3 = 'r.MUSE.2022-06-24T08:46:05.083_tpl.png' \n", - "ASSOC3 = 'ANCILLARY.PREVIEW' \n", - "ASSOM3 = '92deb6cb43321fe6fd30f0287496f8a4' \n", - "ASSON4 = 'r.MUSE.2022-06-24T08:46:05.083_pst.png' \n", - "ASSOC4 = 'ANCILLARY.PREVIEW' \n", - "ASSOM4 = '5d382b64b3ce255702af3420191b6fe3' \n", - "ASSON5 = 'r.MUSE.2022-06-24T09:12:43.926_pst.png' \n", - "ASSOC5 = 'ANCILLARY.PREVIEW' \n", - "ASSOM5 = 'a2b4ec596d8ec69e4847fba92956f03e' \n", - "ORIGFILE= 'MU_SCBC_3250018_2022-06-24T08:46:05.083_WFM-NOAO-N_OBJ.fits' / Origin\n", - "VM_SM = 'SM ' / VM-Visitor Mode; SM-Service Mode \n", - "OB_GRADE= 'A ' / A-fully within B-mostly within C|D-out of specs\n", - "QCFLAG = 00100000000 / quality flag, see release description \n", - "QC_COMM1= 'ROTATE2 ' \n", - "DCARC1 = 'S.MUSE.2022-07-14T15:25:41.243' / archive dp_id, single dcube #1 \n", - "DCORG1 = 'r.MUSE.2022-06-24T08:46:05.083_pst_0000.fits' / origname, #1 \n", - "DCARC2 = 'S.MUSE.2022-07-14T15:26:29.810' / archive dp_id, single dcube #2 \n", - "DCORG2 = 'r.MUSE.2022-06-24T09:12:43.926_pst_0000.fits' / origname, #2 \n", - "CHECKSUM= 'LeUbLZUZLbUbLZUZ' / HDU checksum updated 2022-07-14T15:34:52 \n", - "DATASUM = ' 0' / data unit checksum updated 2022-07-14T15:33:08 \n", - "P3ORIG = 'IDP ' / ESO internal data product " - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hdu[0].header" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "8e1f6086", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3250018" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hdu[0].header['ESO OBS ID']" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "6287ee39", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'Observation in WFM with user defined offsets'" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hdu[0].header['ESO TPL NAME']\n" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "663f5ed8", - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "4d436281", - "metadata": {}, - "outputs": [], - "source": [ - "f = pd.read_csv('/Users/rri38/Documents/work/code/tess/SN_vetting/Sky_grab_for_TESS.csv')" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "2a9494e5", - "metadata": {}, - "outputs": [], - "source": [ - "from astropy.time import Time" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "6d00ded0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "60685.0" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "Time(f['min_date'].iloc[0].split(' ')[0], format='isot', scale='utc').mjd" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "b83573df", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
nametransient_RAtransient_Decmin_magmin_datedisc_datespec_classphot_classtransient_zstatus_idmw_ebvpoint_source_probabilityfilter
02025cxh152.912533-25.15167817.3972212025-01-10 06:10:30.5470002025-02-28 04:36:59.040000NaNNaNNaN70.0400NaNg-ZTF
12025cnu159.277108-7.46793917.5570002025-01-05 12:54:32.5730002025-02-24 08:03:47.998000NaNNaNNaN70.0570NaNorange-ATLAS
22025dgi157.917354-25.90213618.3910002025-01-14 05:58:39.0430002025-03-03 05:24:26.784000NaNNaNNaN10.05200.004cyan-ATLAS
32025azf135.9962830.74037216.8270002024-12-20 15:02:07.3540002025-02-06 22:33:41.184000SN IaNaN0.05300020.03600.003cyan-ATLAS
42024ljc285.42258340.74506717.1000002022-08-09 13:08:462024-06-15 08:15:05SN IIbNaN0.01515470.11700.268V
..........................................
61102019jdy185.852867-14.91073918.5708972009-06-09 06:18:37.5230002019-05-09 07:14:52NaNNaNNaN30.04820.002y
61112019jab68.986725-24.98260818.6995072009-09-16 14:49:16.9930002019-01-08 08:03:50NaNNaNNaN30.04230.010y
61122019jmz211.634621-22.11491118.4825192009-06-22 07:40:12.5930002019-05-25 07:56:38NaNNaNNaN30.06510.001z
61132019bzz79.088542-10.56136116.0305102008-04-11 00:07:172019-03-05 03:02:52NaNNaNNaN3NaNNaNV
61142018kuv84.709833-44.08581914.9592192005-07-12 01:13:042018-12-22 20:00:57NaNNaNNaN30.0316NaNV
\n", - "

6115 rows × 13 columns

\n", - "
" - ], - "text/plain": [ - " name transient_RA transient_Dec min_mag \\\n", - "0 2025cxh 152.912533 -25.151678 17.397221 \n", - "1 2025cnu 159.277108 -7.467939 17.557000 \n", - "2 2025dgi 157.917354 -25.902136 18.391000 \n", - "3 2025azf 135.996283 0.740372 16.827000 \n", - "4 2024ljc 285.422583 40.745067 17.100000 \n", - "... ... ... ... ... \n", - "6110 2019jdy 185.852867 -14.910739 18.570897 \n", - "6111 2019jab 68.986725 -24.982608 18.699507 \n", - "6112 2019jmz 211.634621 -22.114911 18.482519 \n", - "6113 2019bzz 79.088542 -10.561361 16.030510 \n", - "6114 2018kuv 84.709833 -44.085819 14.959219 \n", - "\n", - " min_date disc_date spec_class \\\n", - "0 2025-01-10 06:10:30.547000 2025-02-28 04:36:59.040000 NaN \n", - "1 2025-01-05 12:54:32.573000 2025-02-24 08:03:47.998000 NaN \n", - "2 2025-01-14 05:58:39.043000 2025-03-03 05:24:26.784000 NaN \n", - "3 2024-12-20 15:02:07.354000 2025-02-06 22:33:41.184000 SN Ia \n", - "4 2022-08-09 13:08:46 2024-06-15 08:15:05 SN IIb \n", - "... ... ... ... \n", - "6110 2009-06-09 06:18:37.523000 2019-05-09 07:14:52 NaN \n", - "6111 2009-09-16 14:49:16.993000 2019-01-08 08:03:50 NaN \n", - "6112 2009-06-22 07:40:12.593000 2019-05-25 07:56:38 NaN \n", - "6113 2008-04-11 00:07:17 2019-03-05 03:02:52 NaN \n", - "6114 2005-07-12 01:13:04 2018-12-22 20:00:57 NaN \n", - "\n", - " phot_class transient_z status_id mw_ebv point_source_probability \\\n", - "0 NaN NaN 7 0.0400 NaN \n", - "1 NaN NaN 7 0.0570 NaN \n", - "2 NaN NaN 1 0.0520 0.004 \n", - "3 NaN 0.053000 2 0.0360 0.003 \n", - "4 NaN 0.015154 7 0.1170 0.268 \n", - "... ... ... ... ... ... \n", - "6110 NaN NaN 3 0.0482 0.002 \n", - "6111 NaN NaN 3 0.0423 0.010 \n", - "6112 NaN NaN 3 0.0651 0.001 \n", - "6113 NaN NaN 3 NaN NaN \n", - "6114 NaN NaN 3 0.0316 NaN \n", - "\n", - " filter \n", - "0 g-ZTF \n", - "1 orange-ATLAS \n", - "2 cyan-ATLAS \n", - "3 cyan-ATLAS \n", - "4 V \n", - "... ... \n", - "6110 y \n", - "6111 y \n", - "6112 z \n", - "6113 V \n", - "6114 V \n", - "\n", - "[6115 rows x 13 columns]" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "f" - ] - }, { "cell_type": "code", "execution_count": null, - "id": "e264679a", + "id": "171bf3c9", "metadata": {}, "outputs": [], "source": [] diff --git a/development/kernel_comparison_fqv.pdf b/development/kernel_comparison_fqv.pdf new file mode 100755 index 0000000..aeb69bb Binary files /dev/null and b/development/kernel_comparison_fqv.pdf differ diff --git a/development/run_diag.py b/development/run_diag.py deleted file mode 100644 index 9d1be26..0000000 --- a/development/run_diag.py +++ /dev/null @@ -1,506 +0,0 @@ -import numpy as np -import matplotlib -matplotlib.use('Agg') -import matplotlib.pyplot as plt -from scipy.ndimage import median_filter, percentile_filter, uniform_filter -from joblib import Parallel, delayed - - -def _make_odd(x): - x = max(int(x), 3) - return x if x % 2 == 1 else x + 1 - - -def _get_segments(time, gap_thresh): - """Return list of (start, end) frame index pairs for contiguous segments.""" - dt = np.diff(time) - median_dt = np.median(dt) - breaks = np.where(dt > gap_thresh * median_dt)[0] + 1 - starts = np.concatenate([[0], breaks]) - ends = np.concatenate([breaks, [len(time)]]) - return list(zip(starts.tolist(), ends.tolist())) - - -def adaptive_medfilt_3d( - data, - time=None, - gap_thresh=3.0, - w_min=3, - w_max=51, - grad_smooth_window=11, - low_pct=5, - high_pct=80, - per_pixel_norm=True, - n_levels=7, - n_jobs=1, - metric='deviation', - coarse_windows=(11, 21, 51, 101), - combined_weight=0.5, - local_std_window=21, - local_norm_window=201, - brightness_sigma=2.0, - window_smooth_size=1, - earth_angle=None, - moon_angle=None, - scatter_angle_thresh=50.0, -): - data = np.asarray(data, dtype=float) - T, X, Y = data.shape - - if time is None: - time = np.arange(T, dtype=float) - time = np.asarray(time, dtype=float) - - segments = _get_segments(time, gap_thresh) - - # NaN fill per segment using time coordinates (never interpolates across gaps) - nan_mask = ~np.isfinite(data) - data_filled = data.copy() - if nan_mask.any(): - flat = data_filled.reshape(T, -1) - for s, e in segments: - t_seg = time[s:e] - for j in range(flat.shape[1]): - ts = flat[s:e, j] - bad = ~np.isfinite(ts) - if bad.all(): - flat[s:e, j] = 0.0 - elif bad.any(): - flat[s:e, j] = np.interp(t_seg, t_seg[~bad], ts[~bad]) - - gw = _make_odd(grad_smooth_window) - - # Gradient uses actual time spacing; zeroed at segment boundaries - if metric in ('gradient', 'combined'): - grad = np.gradient(data_filled, time, axis=0) - for s, e in segments: - if s > 0: - grad[s] = 0.0 - if e < T: - grad[e - 1] = 0.0 - grad_var = np.zeros_like(grad) - for s, e in segments: - seg = grad[s:e] - if e - s >= gw: - grad_var[s:e] = np.abs(median_filter(seg, size=(gw, 1, 1), mode='reflect')) - else: - grad_var[s:e] = np.abs(seg) - - # Multi-scale deviation: compute deviation at each coarse window, normalise - # each locally, then take the max — catches variability at any timescale - if metric in ('deviation', 'combined'): - scales = [coarse_windows] if isinstance(coarse_windows, int) else list(coarse_windows) - # Compute all scale deviations first so we can set a common floor - all_devs = [] - for cw in scales: - dev = np.zeros_like(data_filled) - for s, e in segments: - seg = data_filled[s:e] - n = e - s - w = _make_odd(min(cw, n if n % 2 == 1 else n - 1)) - coarse_seg = median_filter(seg, size=(w, 1, 1), mode='reflect') - diff = np.abs(seg - coarse_seg) - dw = _make_odd(min(gw, n if n % 2 == 1 else n - 1)) - dev[s:e] = median_filter(diff, size=(dw, 1, 1), mode='reflect') - all_devs.append(dev) - # Identify stable segments by coefficient of variation of per-frame means. - # A stable segment has low CV (frame means tightly clustered around their - # sigma-clipped mean). For stable segments, skip local normalization and - # force dev_var=0 → w_max. For active segments use the local normalization - # as normal, with cw_min masked in dark frames via bright_mask. - _frame_mean = data_filled.mean(axis=(1, 2)) # (T,) - # Global sigma-clip for bright_mask (used in active segments only) - _clipped = _frame_mean[np.isfinite(_frame_mean)] - for _ in range(5): - _med = np.median(_clipped) - _std = np.std(_clipped) - if _std == 0: - break - _clipped = _clipped[np.abs(_clipped - _med) < brightness_sigma * _std] - brightness_threshold = float(np.mean(_clipped)) + brightness_sigma * float(np.std(_clipped)) - bright_mask = (_frame_mean > brightness_threshold).astype(float)[:, np.newaxis, np.newaxis] - - # Per-segment stability: a segment is stable (force w_max) when it has - # no scattered-light contamination. If earth/moon angle arrays are provided, - # use min(earth, moon) > scatter_angle_thresh as the scatter-free criterion. - # Otherwise fall back to brightness threshold (< 5% active frames). - _frame_active = (_frame_mean > brightness_threshold) - # When angle arrays are provided and scattered light is actually present - # (some frames below scatter_angle_thresh), build a stable_mask to force - # w_max on scatter-free faint frames across all scales. - # Without angles, or when no scatter is present, only mask cw_min (i==0). - _use_stable_mask = False - if earth_angle is not None or moon_angle is not None: - _ea = np.asarray(earth_angle, dtype=float) if earth_angle is not None else np.full(T, np.inf) - _ma = np.asarray(moon_angle, dtype=float) if moon_angle is not None else np.full(T, np.inf) - _scatter_free = np.minimum(_ea, _ma) > scatter_angle_thresh - _has_scatter = (~_scatter_free).any() - if _has_scatter: - _stable_frame = _scatter_free & ~_frame_active - _stable_mask = _stable_frame[:, np.newaxis, np.newaxis].astype(float) - _use_stable_mask = True - - lnw = _make_odd(local_norm_window) - scale_norms = [] - for i, dev in enumerate(all_devs): - scale_floor = max(np.nanpercentile(dev, 75), 1e-10) - g_lo = np.zeros_like(dev) - g_hi = np.zeros_like(dev) - for s, e in segments: - seg_v = dev[s:e] - n = e - s - lw = _make_odd(min(lnw, n if n % 2 == 1 else n - 1)) - g_lo[s:e] = percentile_filter(seg_v, low_pct, size=(lw, 1, 1), mode='reflect') - g_hi[s:e] = percentile_filter(seg_v, high_pct, size=(lw, 1, 1), mode='reflect') - dg = np.maximum(g_hi - g_lo, scale_floor) - norm_scale = np.clip((dev - g_lo) / dg, 0.0, 1.0) - if i == 0: - norm_scale = norm_scale * bright_mask - if _use_stable_mask: - norm_scale = norm_scale * (1.0 - _stable_mask) - scale_norms.append(norm_scale) - dev_var = np.max(np.stack(scale_norms), axis=0) # (T, X, Y) - - # Local std: short-window RMS scatter — captures frame-to-frame variability - # regardless of slow trends or broad peaks - if metric in ('local_std', 'combined'): - lsw = _make_odd(local_std_window) - lstd_var = np.zeros_like(data_filled) - for s, e in segments: - seg = data_filled[s:e] - n = e - s - w = min(lsw, n if n % 2 == 1 else n - 1) - w = _make_odd(w) - m = uniform_filter(seg, size=(w, 1, 1), mode='reflect') - m2 = uniform_filter(seg ** 2, size=(w, 1, 1), mode='reflect') - lstd_var[s:e] = np.sqrt(np.maximum(m2 - m ** 2, 0)) - - def _norm01(x): - lo, hi = np.nanpercentile(x, 1), np.nanpercentile(x, 99) - return np.clip((x - lo) / (hi - lo + 1e-30), 0, 1) - - # dev_var is already locally normalised to [0,1] per scale, max-combined - # other metrics still need normalisation - if metric == 'gradient': - variability = grad_var - elif metric == 'local_std': - variability = lstd_var - elif metric == 'combined': - variability = (1 - combined_weight) * _norm01(grad_var) + combined_weight * _norm01(lstd_var) - elif metric == 'deviation': - variability = dev_var - else: - raise ValueError(f"metric must be 'gradient', 'deviation', 'local_std', or 'combined', got '{metric}'") - - if metric == 'deviation': - norm = dev_var # already in [0,1], normalised per scale - elif local_norm_window is not None: - lnw = _make_odd(local_norm_window) - g_lo = np.zeros_like(variability) - g_hi = np.zeros_like(variability) - for s, e in segments: - seg_var = variability[s:e] - n = e - s - w = _make_odd(min(lnw, n if n % 2 == 1 else n - 1)) - g_lo[s:e] = percentile_filter(seg_var, low_pct, size=(w, 1, 1)) - g_hi[s:e] = percentile_filter(seg_var, high_pct, size=(w, 1, 1)) - dg = np.where((g_hi - g_lo) > 0, g_hi - g_lo, 1.0) - norm = np.clip((variability - g_lo) / dg, 0.0, 1.0) - elif per_pixel_norm: - g_lo = np.nanpercentile(variability, low_pct, axis=0, keepdims=True) - g_hi = np.nanpercentile(variability, high_pct, axis=0, keepdims=True) - dg = np.where((g_hi - g_lo) > 0, g_hi - g_lo, 1.0) - norm = np.clip((variability - g_lo) / dg, 0.0, 1.0) - else: - g_lo = np.nanpercentile(variability, low_pct) - g_hi = np.nanpercentile(variability, high_pct) - dg = np.where((g_hi - g_lo) > 0, g_hi - g_lo, 1.0) - norm = np.clip((variability - g_lo) / dg, 0.0, 1.0) - - raw_w = w_max - norm * (w_max - w_min) - windows = np.round(raw_w).astype(int) - windows += (1 - windows % 2) - windows = np.clip(windows, _make_odd(w_min), _make_odd(w_max)) - - windows_pre_smooth = windows.copy() - - if window_smooth_size > 1: - wsz = _make_odd(window_smooth_size) - smoothed_win = np.empty_like(windows, dtype=float) - for s, e in segments: - n = e - s - w = min(wsz, n if n % 2 == 1 else n - 1) - w = _make_odd(w) - smoothed_win[s:e] = median_filter(windows[s:e].astype(float), size=(w, 1, 1), mode='reflect') - windows = np.round(smoothed_win).astype(int) - windows += (1 - windows % 2) - windows = np.clip(windows, _make_odd(w_min), _make_odd(w_max)) - - levels = np.unique([_make_odd(int(round(w))) for w in np.linspace(w_min, w_max, n_levels)]) - windows_quantized = levels[np.argmin(np.abs(windows[..., np.newaxis] - levels), axis=-1)] - - # Final smoothing per segment to avoid blending across gaps - result = np.empty((T, X, Y)) - for s, e in segments: - seg_data = data_filled[s:e] - seg_wins = windows_quantized[s:e] - seg_levels = np.unique(seg_wins) - - def _smooth_seg(w, seg=seg_data): - return w, median_filter(seg, size=(w, 1, 1), mode='reflect') - - for w, smoothed_w in Parallel(n_jobs=n_jobs)(delayed(_smooth_seg)(w) for w in seg_levels): - result[s:e][seg_wins == w] = smoothed_w[seg_wins == w] - - result[nan_mask] = np.nan - return result, windows, variability, windows_pre_smooth - - -# ── Load data ────────────────────────────────────────────────────────────────── -data = np.load('/Users/rri38/Documents/work/code/tess/tessreduce/development/test_bkg.npy') -time = np.load('/Users/rri38/Documents/work/code/tess/tessreduce/development/test_bkg_time.npy') -print(f"Data shape: {data.shape}") -print(f"Time shape: {time.shape}, range: {time[0]:.4f} – {time[-1]:.4f}") -dt = np.diff(time) -print(f"Median dt: {np.median(dt):.6f}, max dt: {dt.max():.6f}, gap ratio: {dt.max()/np.median(dt):.1f}x") -segs = _get_segments(time, gap_thresh=3.0) -print(f"Segments detected: {len(segs)} — {segs}") - -px, py = 100, 100 -cube = data[:, px:px+1, py:py+1] -print(f"Pixel cube shape: {cube.shape}") -print(f"Pixel value range: {np.nanmin(cube):.4f} – {np.nanmax(cube):.4f}") - -raw_series = cube[:, 0, 0] -T = len(raw_series) -print(f"T = {T}") - -# ── Step 1: Run with winning params (no window smoothing) ────────────────────── -print("\n=== Step 1: Diagnostic run (window_smooth_size=1) ===") -smoothed, windows, variability, windows_pre = adaptive_medfilt_3d( - cube, - time=time, - metric='deviation', - coarse_windows=(11, 21, 51, 101), - low_pct=5, - high_pct=80, - local_norm_window=201, - w_min=3, - w_max=51, - n_jobs=1, - window_smooth_size=1, -) - -sm = smoothed[:, 0, 0] -win = windows[:, 0, 0] -var = variability[:, 0, 0] - -# Stats -print(f"Mean window size: {win.mean():.2f}") -print(f"Std window size: {win.std():.2f}") -frac_min = np.mean(win == _make_odd(3)) -frac_max = np.mean(win == _make_odd(51)) -print(f"Fraction at w_min (3): {frac_min:.4f} ({frac_min*100:.1f}%)") -print(f"Fraction at w_max (51): {frac_max:.4f} ({frac_max*100:.1f}%)") -print(f"Unique window values: {np.unique(win)}") - -# ── Plot 1: Zoomed view 1800–2300 ────────────────────────────────────────────── -z0, z1 = 1800, min(2300, T) -frames_z = np.arange(z0, z1) -fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(14, 10), sharex=True) - -ax1.plot(frames_z, raw_series[z0:z1], lw=0.8, color='steelblue', label='Raw') -ax1.plot(frames_z, sm[z0:z1], lw=1.2, color='firebrick', label='Smoothed') -ax1.set_ylabel('Flux') -ax1.set_title('Pixel (100,100) — zoomed frames 1800–2300') -ax1.legend(fontsize=8) - -ax_win = ax2 -ax_win.plot(frames_z, win[z0:z1], color='darkorange', lw=0.7, label='Window size') -ax_win.set_ylabel('Window size') -ax_win.set_title('Adaptive window sizes (no smoothing)') -ax_win.legend(fontsize=8) - -ax3.plot(frames_z, var[z0:z1], color='purple', lw=0.7, label='Variability metric') -ax3.set_ylabel('Variability') -ax3.set_xlabel('Frame') -ax3.set_title('Raw variability metric (deviation-based)') -ax3.legend(fontsize=8) - -plt.tight_layout() -plt.savefig('/Users/rri38/Documents/work/code/tess/tessreduce/development/diag_zoom_2000.png', dpi=120) -plt.close() -print("Saved diag_zoom_2000.png") - -# Check variability smoothness in the zoom region -var_z = var[z0:z1] -var_diffs = np.diff(var_z) -print(f"\nVariability in 1800–2300:") -print(f" mean={var_z.mean():.4f}, std={var_z.std():.4f}") -print(f" mean |diff| (roughness): {np.abs(var_diffs).mean():.6f}") -print(f" max |diff|: {np.abs(var_diffs).max():.6f}") - -# ── Step 2: Test window_smooth_sizes ────────────────────────────────────────── -print("\n=== Step 2: Testing window_smooth_size values ===") - -# Peak/baseline detection helpers -def detect_peaks_adaptive(series, coarse_bw=201, prom_thresh_mad_mult=1.5): - """Return boolean mask of 'peak' frames.""" - cw = _make_odd(coarse_bw) - baseline = median_filter(series, size=cw, mode='reflect') - detrended = series - baseline - mad = np.median(np.abs(detrended - np.median(detrended))) - threshold = prom_thresh_mad_mult * mad - return detrended > threshold, detrended, baseline, threshold - -def compute_residuals(raw, smoothed, peak_mask): - residuals = np.abs(raw - smoothed) - peak_res = residuals[peak_mask].mean() if peak_mask.any() else np.nan - base_res = residuals[~peak_mask].mean() if (~peak_mask).any() else np.nan - return peak_res, base_res - -smooth_sizes = [1, 5, 11, 21, 31] -results = {} - -for wsz in smooth_sizes: - sm_w, win_w, _, _ = adaptive_medfilt_3d( - cube, - time=time, - metric='deviation', - coarse_windows=(11, 21, 51, 101), - low_pct=5, - high_pct=80, - local_norm_window=201, - w_min=3, - w_max=51, - n_jobs=1, - window_smooth_size=wsz, - ) - sm_1d = sm_w[:, 0, 0] - win_1d = win_w[:, 0, 0] - - peak_mask, detrended, baseline, threshold = detect_peaks_adaptive(raw_series) - peak_res, base_res = compute_residuals(raw_series, sm_1d, peak_mask) - - n_switches = np.sum(np.diff(win_1d) != 0) - win_std = win_1d.std() - win_mean = win_1d.mean() - fmin = np.mean(win_1d == _make_odd(3)) - fmax = np.mean(win_1d == _make_odd(51)) - - results[wsz] = { - 'smoothed': sm_1d, - 'windows': win_1d, - 'peak_res': peak_res, - 'base_res': base_res, - 'win_mean': win_mean, - 'win_std': win_std, - 'n_switches': n_switches, - 'fmin': fmin, - 'fmax': fmax, - 'peak_mask': peak_mask, - 'detrended': detrended, - 'threshold': threshold, - } - - print(f"\nwindow_smooth_size={wsz}:") - print(f" win mean={win_mean:.2f}, std={win_std:.2f}, n_switches={n_switches}") - print(f" frac@w_min={fmin:.3f}, frac@w_max={fmax:.3f}") - print(f" peak_residual={peak_res:.5f}, base_residual={base_res:.5f}") - ratio = peak_res / base_res if base_res > 0 else np.nan - print(f" peak/base ratio={ratio:.3f}") - -# Determine best: want low base residual, retain peak residual, fewer switches -# Score: lower is better — base_res (main), penalise very high n_switches -# We want ratio reasonably high (peaks preserved) and base_res low -print("\n=== Score summary ===") -for wsz in smooth_sizes: - r = results[wsz] - print(f" wsz={wsz:2d}: base_res={r['base_res']:.5f}, peak_res={r['peak_res']:.5f}, " - f"ratio={r['peak_res']/r['base_res']:.3f}, n_switches={r['n_switches']}") - -# Choose best: wsz that gives fewest switches with stable base/peak residuals -# Use elbow: pick smallest wsz where n_switches drops by >50% from wsz=1 -base_switches = results[1]['n_switches'] -best_wsz = 1 -for wsz in smooth_sizes[1:]: - if results[wsz]['n_switches'] < 0.4 * base_switches: - best_wsz = wsz - break - -print(f"\nSelected best window_smooth_size = {best_wsz}") - -# ── Step 3: Final 4-panel diagnostic ────────────────────────────────────────── -print(f"\n=== Step 3: Saving adaptive_smooth_final.png with wsz={best_wsz} ===") - -r = results[best_wsz] -r_raw = results[1] -sm_best = r['smoothed'] -win_best = r['windows'] -win_raw = r_raw['windows'] -peak_mask = r['peak_mask'] -detrended = r['detrended'] - -frames = np.arange(T) - -fig, axes = plt.subplots(4, 1, figsize=(16, 16)) -fig.suptitle(f'Pixel (100,100) — adaptive_medfilt_3d | window_smooth_size={best_wsz}', fontsize=12) - -# Panel 1: raw + smoothed + peak shading -ax = axes[0] -ax.plot(frames, raw_series, lw=0.6, color='steelblue', alpha=0.7, label='Raw') -ax.plot(frames, sm_best, lw=1.2, color='firebrick', label=f'Smoothed (wsz={best_wsz})') -# Shade peak regions -in_peak = False -for i in range(T): - if peak_mask[i] and not in_peak: - start = i - in_peak = True - elif not peak_mask[i] and in_peak: - ax.axvspan(start, i, alpha=0.15, color='gold') - in_peak = False -if in_peak: - ax.axvspan(start, T, alpha=0.15, color='gold') -ax.set_ylabel('Flux') -ax.set_title('Raw signal + smoothed (peak regions shaded)') -ax.legend(fontsize=8) - -# Panel 2: original vs smoothed window sizes -ax = axes[1] -ax.plot(frames, win_raw, lw=0.5, color='gray', alpha=0.7, label='Original windows (wsz=1)') -ax.plot(frames, win_best, lw=1.0, color='darkorange', label=f'Smoothed windows (wsz={best_wsz})') -ax.set_ylabel('Window size') -ax.set_title('Window size: original vs smoothed') -ax.legend(fontsize=8) - -# Panel 3: zoomed 1800–2300 -ax = axes[2] -z0, z1 = 1800, min(2300, T) -fz = np.arange(z0, z1) -ax.plot(fz, raw_series[z0:z1], lw=0.8, color='steelblue', alpha=0.8, label='Raw') -ax.plot(fz, sm_best[z0:z1], lw=1.3, color='firebrick', label=f'Smoothed (wsz={best_wsz})') -ax_r = ax.twinx() -ax_r.plot(fz, win_best[z0:z1], color='darkorange', lw=0.8, alpha=0.6, label='Window') -ax_r.set_ylabel('Window size', color='darkorange') -ax_r.tick_params(axis='y', labelcolor='darkorange') -ax.set_ylabel('Flux') -ax.set_title('Zoom: frames 1800–2300') -lines1, labels1 = ax.get_legend_handles_labels() -lines2, labels2 = ax_r.get_legend_handles_labels() -ax.legend(lines1 + lines2, labels1 + labels2, fontsize=8) - -# Panel 4: detrended signal with peaks marked -ax = axes[3] -ax.plot(frames, detrended, lw=0.7, color='darkgreen', label='Detrended (raw − coarse baseline)') -ax.axhline(r['threshold'], color='red', ls='--', lw=0.8, label=f'Threshold (1.5×MAD={r["threshold"]:.4f})') -ax.scatter(frames[peak_mask], detrended[peak_mask], s=4, color='red', alpha=0.5, label='Peaks') -ax.set_xlabel('Frame') -ax.set_ylabel('Residual flux') -ax.set_title('Detrended signal with detected peaks') -ax.legend(fontsize=8) - -plt.tight_layout() -plt.savefig('/Users/rri38/Documents/work/code/tess/tessreduce/development/adaptive_smooth_final.png', dpi=120) -plt.close() -print("Saved adaptive_smooth_final.png") -print("\nDone.") diff --git a/development/run_diag2.py b/development/run_diag2.py deleted file mode 100644 index b2be476..0000000 --- a/development/run_diag2.py +++ /dev/null @@ -1,348 +0,0 @@ -""" -Deeper look: why doesn't wsz=5/11 change n_switches? -And examine the actual window pattern visually. -""" -import numpy as np -import matplotlib -matplotlib.use('Agg') -import matplotlib.pyplot as plt -from scipy.ndimage import median_filter -from joblib import Parallel, delayed - - -def _make_odd(x): - x = max(int(x), 3) - return x if x % 2 == 1 else x + 1 - - -def adaptive_medfilt_3d_debug( - data, - w_min=3, - w_max=51, - grad_smooth_window=11, - low_pct=5, - high_pct=90, - per_pixel_norm=True, - n_levels=7, - n_jobs=1, - metric='combined', - coarse_window=101, - combined_weight=1.0, - window_smooth_size=1, -): - data = np.asarray(data, dtype=float) - T, X, Y = data.shape - - nan_mask = ~np.isfinite(data) - data_filled = data.copy() - if nan_mask.any(): - t_ax = np.arange(T, dtype=float) - flat = data_filled.reshape(T, -1) - for j in range(flat.shape[1]): - ts = flat[:, j] - bad = ~np.isfinite(ts) - if bad.all(): - flat[:, j] = 0.0 - elif bad.any(): - flat[:, j] = np.interp(t_ax, t_ax[~bad], ts[~bad]) - - gw = _make_odd(grad_smooth_window) - grad = np.gradient(data_filled, axis=0) - grad_var = np.abs(median_filter(grad, size=(gw, 1, 1), mode='reflect')) - cw = _make_odd(coarse_window) - coarse = median_filter(data_filled, size=(cw, 1, 1), mode='reflect') - dev_var = np.abs(data_filled - coarse) - dev_var = median_filter(dev_var, size=(gw, 1, 1), mode='reflect') - - def _norm01(x): - lo, hi = np.nanpercentile(x, 1), np.nanpercentile(x, 99) - return np.clip((x - lo) / (hi - lo + 1e-30), 0, 1) - variability = (1 - combined_weight) * _norm01(grad_var) + combined_weight * _norm01(dev_var) - - g_lo = np.nanpercentile(variability, low_pct, axis=0, keepdims=True) - g_hi = np.nanpercentile(variability, high_pct, axis=0, keepdims=True) - dg = np.where((g_hi - g_lo) > 0, g_hi - g_lo, 1.0) - norm = np.clip((variability - g_lo) / dg, 0.0, 1.0) - - raw = w_max - norm * (w_max - w_min) - windows_raw_cont = raw.copy() # continuous, before rounding - windows = np.round(raw).astype(int) - windows += (1 - windows % 2) - windows = np.clip(windows, _make_odd(w_min), _make_odd(w_max)) - windows_pre = windows.copy() - - if window_smooth_size > 1: - wsz = _make_odd(window_smooth_size) - windows = median_filter(windows.astype(float), size=(wsz, 1, 1), mode='reflect') - windows = np.round(windows).astype(int) - windows += (1 - windows % 2) - windows = np.clip(windows, _make_odd(w_min), _make_odd(w_max)) - - windows_post = windows.copy() - - levels = np.unique([_make_odd(int(round(w))) for w in np.linspace(w_min, w_max, n_levels)]) - windows_q = levels[np.argmin(np.abs(windows[..., np.newaxis] - levels), axis=-1)] - - def _smooth(w): - return w, median_filter(data_filled, size=(w, 1, 1), mode='reflect') - - result = np.empty((T, X, Y)) - for w, smoothed_w in Parallel(n_jobs=n_jobs)(delayed(_smooth)(w) for w in levels): - result[windows_q == w] = smoothed_w[windows_q == w] - - result[nan_mask] = np.nan - return result, windows_q, variability, windows_pre, windows_post, windows_raw_cont - - -data = np.load('/Users/rri38/Documents/work/code/tess/tessreduce/development/test_bkg.npy') -cube = data[:, 100:101, 100:101] -raw_series = cube[:, 0, 0] -T = len(raw_series) -print(f"T={T}") - -# Run wsz=1 and wsz=31 in debug mode -print("\n--- wsz=1 ---") -sm1, wq1, var1, wpre1, wpost1, wrc1 = adaptive_medfilt_3d_debug(cube, window_smooth_size=1, - combined_weight=1.0, coarse_window=101, low_pct=5, high_pct=90) -wq1d = wq1[:, 0, 0] -wpre1d = wpre1[:, 0, 0] -wrc1d = wrc1[:, 0, 0] -print(f" unique quantized levels: {np.unique(wq1d)}") -print(f" n_switches (pre-quant): {np.sum(np.diff(wpre1d) != 0)}") -print(f" n_switches (quantized): {np.sum(np.diff(wq1d) != 0)}") - -print("\n--- wsz=5 ---") -sm5, wq5, var5, wpre5, wpost5, wrc5 = adaptive_medfilt_3d_debug(cube, window_smooth_size=5, - combined_weight=1.0, coarse_window=101, low_pct=5, high_pct=90) -wq5d = wq5[:, 0, 0] -wpost5d = wpost5[:, 0, 0] -print(f" unique quantized levels: {np.unique(wq5d)}") -print(f" n_switches (post-smooth, pre-quant): {np.sum(np.diff(wpost5d) != 0)}") -print(f" n_switches (quantized): {np.sum(np.diff(wq5d) != 0)}") - -print("\n--- wsz=11 ---") -sm11, wq11, var11, wpre11, wpost11, wrc11 = adaptive_medfilt_3d_debug(cube, window_smooth_size=11, - combined_weight=1.0, coarse_window=101, low_pct=5, high_pct=90) -wq11d = wq11[:, 0, 0] -wpost11d = wpost11[:, 0, 0] -print(f" unique quantized levels: {np.unique(wq11d)}") -print(f" n_switches (post-smooth, pre-quant): {np.sum(np.diff(wpost11d) != 0)}") -print(f" n_switches (quantized): {np.sum(np.diff(wq11d) != 0)}") - -print("\n--- wsz=21 ---") -sm21, wq21, var21, wpre21, wpost21, wrc21 = adaptive_medfilt_3d_debug(cube, window_smooth_size=21, - combined_weight=1.0, coarse_window=101, low_pct=5, high_pct=90) -wq21d = wq21[:, 0, 0] -wpost21d = wpost21[:, 0, 0] -print(f" unique quantized levels: {np.unique(wq21d)}") -print(f" n_switches (post-smooth, pre-quant): {np.sum(np.diff(wpost21d) != 0)}") -print(f" n_switches (quantized): {np.sum(np.diff(wq21d) != 0)}") - -print("\n--- wsz=31 ---") -sm31, wq31, var31, wpre31, wpost31, wrc31 = adaptive_medfilt_3d_debug(cube, window_smooth_size=31, - combined_weight=1.0, coarse_window=101, low_pct=5, high_pct=90) -wq31d = wq31[:, 0, 0] -wpost31d = wpost31[:, 0, 0] -print(f" unique quantized levels: {np.unique(wq31d)}") -print(f" n_switches (post-smooth, pre-quant): {np.sum(np.diff(wpost31d) != 0)}") -print(f" n_switches (quantized): {np.sum(np.diff(wq31d) != 0)}") - -# Look at zoom region for switches -z0, z1 = 1800, 2300 -print(f"\nIn zoom region {z0}-{z1}:") -for label, arr in [('wsz=1', wq1d), ('wsz=5', wq5d), ('wsz=11', wq11d), ('wsz=21', wq21d), ('wsz=31', wq31d)]: - ns = np.sum(np.diff(arr[z0:z1]) != 0) - print(f" {label}: {ns} switches") - -# Understand why small wsz doesn't reduce switches: the window field must -# switch very rapidly with step > wsz width, so median can't resolve it. -# Check run-length stats -def run_lengths(arr): - """Return lengths of constant runs.""" - diffs = np.concatenate(([1], np.diff(arr) != 0, [1])) - starts = np.where(diffs)[0] - return np.diff(starts) - -print("\nRun-length stats for pre-smooth window field:") -rls = run_lengths(wpre1d) -print(f" n_runs={len(rls)}, mean_run={rls.mean():.1f}, median_run={np.median(rls):.1f}, max_run={rls.max()}") -print(f" fraction of single-frame runs: {np.mean(rls == 1):.3f}") - -print("\nRun-length stats for post-smooth (wsz=11):") -rls11 = run_lengths(wpost11d) -print(f" n_runs={len(rls11)}, mean_run={rls11.mean():.1f}, median_run={np.median(rls11):.1f}, max_run={rls11.max()}") -print(f" fraction of single-frame runs: {np.mean(rls11 == 1):.3f}") - -print("\nRun-length stats for post-smooth (wsz=31):") -rls31 = run_lengths(wpost31d) -print(f" n_runs={len(rls31)}, mean_run={rls31.mean():.1f}, median_run={np.median(rls31):.1f}, max_run={rls31.max()}") -print(f" fraction of single-frame runs: {np.mean(rls31 == 1):.3f}") - -# Key insight: the oscillation happens at the QUANTIZATION stage. -# Check the continuous window field before quantization -print("\nContinuous window field (pre-round) in zoom region 1800-2300:") -wrc_z = wrc1d[1800:2300] -print(f" mean={wrc_z.mean():.2f}, std={wrc_z.std():.2f}") -print(f" fraction within 1 unit of even->odd boundary: {np.mean(np.abs(wrc_z - np.round(wrc_z)) > 0.4):.3f}") -# Look at actual values -print(f" first 20 values: {wrc_z[:20]}") - -# The real problem: after rounding and odd-enforcement, even small variations -# near boundaries cause oscillation. Smoothing the integer field doesn't help -# if the continuous field is already near boundaries. -# Solution: smooth the CONTINUOUS field before rounding, then quantize. - -# Also check: what fraction of the window field is near a level boundary? -levels = np.unique([_make_odd(int(round(w))) for w in np.linspace(3, 51, 7)]) -print(f"\nLevels used: {levels}") -# Distance to nearest level boundary -def dist_to_nearest_level(v, levels): - dists = np.abs(v[:, None] - levels[None, :]) - return dists.min(axis=1) - -# Now make the final 4-panel plot using wsz=31 (most visible difference) -# alongside wsz=1 for comparison -best_wsz = 31 - -def detect_peaks_adaptive(series, coarse_bw=201, prom_thresh_mad_mult=1.5): - cw = _make_odd(coarse_bw) - baseline = median_filter(series, size=cw, mode='reflect') - detrended = series - baseline - mad = np.median(np.abs(detrended - np.median(detrended))) - threshold = prom_thresh_mad_mult * mad - return detrended > threshold, detrended, baseline, threshold - -peak_mask, detrended, baseline, threshold = detect_peaks_adaptive(raw_series) -sm_best = sm31[:, 0, 0] -win_best = wq31d -win_raw = wq1d - -frames = np.arange(T) - -fig, axes = plt.subplots(4, 1, figsize=(16, 18)) -fig.suptitle(f'Pixel (100,100) — adaptive_medfilt_3d | window_smooth_size={best_wsz}', fontsize=13) - -# Panel 1: raw + smoothed + peak shading -ax = axes[0] -ax.plot(frames, raw_series, lw=0.5, color='steelblue', alpha=0.7, label='Raw') -ax.plot(frames, sm_best, lw=1.2, color='firebrick', label=f'Smoothed (wsz={best_wsz})') -in_peak = False -for i in range(T): - if peak_mask[i] and not in_peak: - start = i - in_peak = True - elif not peak_mask[i] and in_peak: - ax.axvspan(start, i, alpha=0.12, color='gold') - in_peak = False -if in_peak: - ax.axvspan(start, T, alpha=0.12, color='gold') -ax.set_ylabel('Flux') -ax.set_title('Raw signal + smoothed (peak regions shaded in gold)') -ax.legend(fontsize=8) - -# Panel 2: original vs smoothed window sizes -ax = axes[1] -ax.plot(frames, win_raw, lw=0.5, color='gray', alpha=0.6, label='Window sizes (wsz=1, no smoothing)') -ax.plot(frames, win_best, lw=1.0, color='darkorange', alpha=0.9, label=f'Window sizes (wsz={best_wsz})') -ax.set_ylabel('Window size') -ax.set_title('Window size: original (noisy) vs smoothed') -ax.legend(fontsize=8) - -# Panel 3: zoomed 1800–2300 -ax = axes[2] -fz = np.arange(z0, z1) -ax.plot(fz, raw_series[z0:z1], lw=0.8, color='steelblue', alpha=0.8, label='Raw') -ax.plot(fz, sm_best[z0:z1], lw=1.4, color='firebrick', label=f'Smoothed (wsz={best_wsz})') -ax_r = ax.twinx() -ax_r.plot(fz, win_raw[z0:z1], lw=0.6, color='gray', alpha=0.5, label='win (wsz=1)') -ax_r.plot(fz, win_best[z0:z1], lw=1.0, color='darkorange', alpha=0.8, label=f'win (wsz={best_wsz})') -ax_r.set_ylabel('Window size', color='darkorange') -ax_r.tick_params(axis='y', labelcolor='darkorange') -ax.set_ylabel('Flux') -ax.set_title('Zoom: frames 1800–2300') -lines1, labels1 = ax.get_legend_handles_labels() -lines2, labels2 = ax_r.get_legend_handles_labels() -ax.legend(lines1 + lines2, labels1 + labels2, fontsize=7, loc='upper left') - -# Panel 4: detrended signal with peaks marked -ax = axes[3] -ax.plot(frames, detrended, lw=0.6, color='darkgreen', label='Detrended (raw − coarse baseline)') -ax.axhline(threshold, color='red', ls='--', lw=0.9, label=f'Threshold (1.5×MAD = {threshold:.4f})') -ax.scatter(frames[peak_mask], detrended[peak_mask], s=3, color='red', alpha=0.5, label=f'Peaks ({peak_mask.sum()} frames)') -ax.set_xlabel('Frame') -ax.set_ylabel('Residual flux') -ax.set_title('Detrended signal with detected peaks') -ax.legend(fontsize=8) - -plt.tight_layout() -plt.savefig('/Users/rri38/Documents/work/code/tess/tessreduce/development/adaptive_smooth_final.png', dpi=120) -plt.close() -print("\nSaved adaptive_smooth_final.png") - -# Also save the zoom diagnostic as requested -fig, axes = plt.subplots(3, 1, figsize=(14, 12), sharex=True) -var1d = var1[:, 0, 0] -fz = np.arange(z0, z1) - -ax = axes[0] -ax.plot(fz, raw_series[z0:z1], lw=0.7, color='steelblue', label='Raw') -ax.plot(fz, sm1[:, 0, 0][z0:z1], lw=1.1, color='firebrick', label='Smoothed (wsz=1)') -ax.set_ylabel('Flux') -ax.set_title('Pixel (100,100): frames 1800–2300 — raw and smoothed') -ax.legend(fontsize=8) - -ax = axes[1] -ax.plot(fz, win_raw[z0:z1], lw=0.6, color='gray', alpha=0.7, label='Quantized windows (wsz=1)') -ax_w = ax.twinx() -ax_w.plot(fz, wrc1d[z0:z1], lw=0.8, color='navy', alpha=0.6, label='Continuous raw (pre-round)') -ax_w.set_ylabel('Continuous window value', color='navy') -ax_w.tick_params(axis='y', labelcolor='navy') -ax.set_ylabel('Quantized window size', color='gray') -ax.set_title('Window sizes (quantized) and continuous field') -lines1, labels1 = ax.get_legend_handles_labels() -lines2, labels2 = ax_w.get_legend_handles_labels() -ax.legend(lines1 + lines2, labels1 + labels2, fontsize=7) - -ax = axes[2] -ax.plot(fz, var1d[z0:z1], lw=0.7, color='purple', label='Variability metric') -ax.set_ylabel('Variability') -ax.set_xlabel('Frame') -ax.set_title('Raw variability metric in zoom region') -ax.legend(fontsize=8) - -plt.tight_layout() -plt.savefig('/Users/rri38/Documents/work/code/tess/tessreduce/development/diag_zoom_2000.png', dpi=120) -plt.close() -print("Saved diag_zoom_2000.png (updated)") - -print("\n=== FINAL REPORT ===") -print(f"Pixel (100,100), T={T}") -print(f"\nWindow size stats (wsz=1, no smoothing):") -print(f" mean={wq1d.mean():.2f}, std={wq1d.std():.2f}") -print(f" n_switches={np.sum(np.diff(wq1d)!=0)}, mean run={run_lengths(wq1d).mean():.1f} frames") -print(f" frac@w_min={np.mean(wq1d==3):.3f}, frac@w_max={np.mean(wq1d==51):.3f}") - -for wsz, wqd in [(5, wq5d), (11, wq11d), (21, wq21d), (31, wq31d)]: - print(f"\nWindow size stats (wsz={wsz}):") - print(f" mean={wqd.mean():.2f}, std={wqd.std():.2f}") - print(f" n_switches={np.sum(np.diff(wqd)!=0)}, mean run={run_lengths(wqd).mean():.1f} frames") - print(f" frac@w_min={np.mean(wqd==3):.3f}, frac@w_max={np.mean(wqd==51):.3f}") - -print(f"\nPeak/baseline residuals:") -def compute_residuals(raw, sm, pm): - r = np.abs(raw - sm) - return r[pm].mean() if pm.any() else np.nan, r[~pm].mean() if (~pm).any() else np.nan - -for wsz, smd in [(1, sm1[:, 0, 0]), (5, sm5[:, 0, 0]), (11, sm11[:, 0, 0]), - (21, sm21[:, 0, 0]), (31, sm31[:, 0, 0])]: - pr, br = compute_residuals(raw_series, smd, peak_mask) - print(f" wsz={wsz:2d}: peak_res={pr:.5f}, base_res={br:.5f}, ratio={pr/br:.3f}") - -print(f"\nDiagnosis of oscillation:") -rls = run_lengths(wpre1d) -print(f" Pre-smooth window field: {len(rls)} runs, mean={rls.mean():.1f}, median={np.median(rls):.0f} frames/run") -print(f" Fraction single-frame runs: {np.mean(rls==1):.3f}") -print(f" Root cause: window field oscillates at period ~{2*np.median(rls):.0f} frames") -print(f" Smoothing is partially absorbed by quantization (n_levels=7 with step-size ~8)") -print(f" wsz=31 gives best switch reduction: {np.sum(np.diff(wq1d)!=0)} -> {np.sum(np.diff(wq31d)!=0)} ({100*(1-np.sum(np.diff(wq31d)!=0)/np.sum(np.diff(wq1d)!=0)):.0f}% reduction)") -print(f"\nBest window_smooth_size = 31 (largest switch reduction with acceptable residual increase)") diff --git a/development/sn2020aoi_cal.pdf b/development/sn2020aoi_cal.pdf new file mode 100755 index 0000000..cfcf173 Binary files /dev/null and b/development/sn2020aoi_cal.pdf differ diff --git a/development/sn2020aoi_cal.png b/development/sn2020aoi_cal.png new file mode 100755 index 0000000..bd11e3d Binary files /dev/null and b/development/sn2020aoi_cal.png differ diff --git a/development/stack_ref.ipynb b/development/stack_ref.ipynb deleted file mode 100644 index 3195c2a..0000000 --- a/development/stack_ref.ipynb +++ /dev/null @@ -1,21739 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "9258d3e2", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import tessreduce as tr\n", - "%matplotlib notebook" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f00f5ed5", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", - "made source mask\n", - "calculating background\n", - "background subtracted\n", - "aligning images\n", - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n", - "background correlation correction\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess = tr.tessreduce(tpf='../../SN_individual/grb_test.fits',calibrate=False,diff=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "0882c035", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.5074744185183834, 0.4845421995512588, 2.9524085215662574)" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(tess.lc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "5a77c499", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Optimal PSF shift: [-0.79997333 -0.8 ]\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "l = tess.diff_lc(phot_method='psf',plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "942af385", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.39491730756917903, 0.2551290720986874, 3.1624806280483053)" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(l[0][1])" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "6b7b72b2", - "metadata": {}, - "outputs": [], - "source": [ - "tess.flux = tr.strip_units(tess.tpf.flux)\n", - "tess.flux = tess.flux / tess.qe\n", - "\n", - "if tess.align:\n", - " tess.shift_images()" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "8f1812cc", - "metadata": {}, - "outputs": [], - "source": [ - "ref = tess.flux[tess.ref_ind]" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "d757549a", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(ref,vmax=500)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "eeb57573", - "metadata": {}, - "outputs": [], - "source": [ - "bright = np.nansum(tess.flux,axis=(1,2))" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "id": "0a2f562d", - "metadata": {}, - "outputs": [], - "source": [ - "m,med,std = tr.sigma_clipped_stats(tess.flux,axis=(1,2))\n", - "sm, smed, sstd = tr.sigma_clipped_stats(std)\n", - "ind = np.where((std < (smed + 3*sstd)) & (std > (smed - 3*sstd)))[0]\n", - "stack = np.nanmedian(tess.flux[ind],axis=0)" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "id": "014fe6e8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(135.18896629751455, 130.50159287107397, 15.036304144564637)" - ] - }, - "execution_count": 63, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(ref)" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "id": "57235c4d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(143.4577684244843, 138.9558073961959, 14.922821471446785)" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(stack)" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "5c422e71", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.subplot(121)\n", - "plt.imshow(ref,vmax=200,vmin=100)\n", - "plt.subplot(122)\n", - "plt.imshow(stack,vmax=200,vmin=100)" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "id": "aaa9b17d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "-7.128225745011747" - ] - }, - "execution_count": 74, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.median(d2)" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "id": "afca5ba6", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 80, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "d1 = tess.flux[100] - ref\n", - "d2 = tess.flux[100] - stack\n", - "d2 -= np.median(d2)\n", - "d1 -= np.median(d1)\n", - "plt.figure()\n", - "plt.subplot(121)\n", - "plt.imshow(d1,vmin=np.nanpercentile(d1,5),vmax=np.percentile(d1,90))#,vmax=200,vmin=100)\n", - "plt.colorbar()\n", - "plt.subplot(122)\n", - "plt.imshow(d2,vmin=np.nanpercentile(d2,5),vmax=np.percentile(d2,90))#,vmax=200,vmin=100)\n", - "plt.colorbar()" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "id": "ec5d950d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.0176669473270038, -0.0159029262837862, 1.7082819811977064)" - ] - }, - "execution_count": 81, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(d1)" - ] - }, - { - "cell_type": "code", - "execution_count": 82, - "id": "6e235c5d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "217.53101395971555" - ] - }, - "execution_count": 82, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.sum(d2)" - ] - }, - { - "cell_type": "code", - "execution_count": 83, - "id": "fc275acd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "397.4053733660529" - ] - }, - "execution_count": 83, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.sum(d1)" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "id": "7dd18383", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.017184440942750786, -0.006614898391653412, 0.9010009546158947)" - ] - }, - "execution_count": 84, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(d2)" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "408061a6", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(std)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "0bf93bd4", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "(array([[ 5.98818366e+04, 5.98818389e+04, 5.98818413e+04, ...,\n", - " 5.99095469e+04, 5.99095492e+04, 5.99095515e+04],\n", - " [-1.07113961e+01, -1.46373448e+01, -1.85746908e+01, ...,\n", - " -2.95190204e+00, -8.43048290e+00, -1.35432273e+01],\n", - " [ 3.20643640e-01, 1.81864970e-01, 1.58968489e-01, ...,\n", - " 2.36887899e-01, 1.33115664e+01, 2.57972995e-01]]),\n", - " array([[ 5.98818366e+04, 5.98818389e+04, 5.98818413e+04, ...,\n", - " 5.99095469e+04, 5.99095492e+04, 5.99095515e+04],\n", - " [ 2.52676986e-01, 6.37262803e-01, -4.82652514e-01, ...,\n", - " 1.12220358e+00, 3.91216858e-01, 4.22198838e-01],\n", - " [ 2.20838380e+00, 2.30175807e+00, 1.54319803e+00, ...,\n", - " 9.31596251e-01, 7.92200556e-01, 9.16807684e-01]]))" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.diff_lc(phot_method='psf',plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "cf92206f", - "metadata": {}, - "outputs": [], - "source": [ - "import power_scan as ps" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "56019051", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([59881.83663189, 59881.83894672, 59881.84126155, ...,\n", - " 59909.54690211, 59909.54921685, 59909.55153158])" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.mjd" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "f2476b4e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "making cube\n", - "(11692,)\n", - "finding sources\n", - "cleaning detections\n", - "finding peak frequency\n", - "finding fundamental period\n" - ] - } - ], - "source": [ - "power = ps.periodogram_detection(tess.mjd,tess.flux)" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "ff6bc031", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "power.plot_object()" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "72da76a5", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(np.nanmean(tess.tpf.flux.value,axis=0))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3eab9e80", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.2" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/development/starfind_test.ipynb b/development/starfind_test.ipynb index a75befa..6886cb4 100644 --- a/development/starfind_test.ipynb +++ b/development/starfind_test.ipynb @@ -2,4137 +2,41 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, - "id": "f175f39e", - "metadata": {}, - "outputs": [], - "source": [ - "import astroalign as aa\n", - "\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "%matplotlib notebook\n", - "import tessreduce as tr\n", - "from tessreduce import *" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "4a9a9b4f", - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "made source mask\n", - "calculating background\n", - "background subtracted\n", - "aligning images\n", - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n", - "background correlation correction\n", - "kernels matched\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess = tr.tessreduce(tpf='../../SN_individual/2020ghq/s23.fits',num_cores=-2,calibrate=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "50123613", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.tpf.quality > 0)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "a39c9871", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "lc,s = tessa.diff_lc(x=46,y=46,phot_method='psf',plot=True);" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "f24f5e5d", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": 2, + "id": "1a4a8067", + "metadata": {}, + "outputs": [], "source": [ - "plt.figure()\n", - "#plt.plot(tess.flux[:,45,45],'.')\n", - "plt.plot(tess.flux[:,44,45],'.')\n", - "#plt.plot(tess.shift[:,0])" + "import astroalign as aa\n", + "\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib notebook\n", + "import tessreduce as tr\n", + "from tessreduce import *" ] }, { "cell_type": "code", - "execution_count": 29, - "id": "f796ff12", - "metadata": {}, + "execution_count": 6, + "id": "533e7ef9", + "metadata": { + "scrolled": false + }, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "made reference\n", + "7\n", + "made source mask\n", + "calculating background\n", + "background subtracted\n", + "Field calibration\n", + "Target is above -30 dec, calibrating to PS1 photometry.\n" + ] + }, { "data": { "application/javascript": [ @@ -4330,15 +234,6 @@ " }\n", "\n", " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\n", " var nentries = entries.length;\n", " for (var i = 0; i < nentries; i++) {\n", " var entry = entries[i];\n", @@ -4386,7 +281,7 @@ " // 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 (width != 0 && height != 0) {\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", " fig.request_resize(width, height);\n", " }\n", " }\n", @@ -4735,22 +630,6 @@ " };\n", "};\n", "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", "\n", "/*\n", " * return a copy of an object with only non-object keys\n", @@ -4782,7 +661,6 @@ " y: y,\n", " button: event.button,\n", " step: event.step,\n", - " modifiers: getModifiers(event),\n", " guiEvent: simpleKeys(event),\n", " });\n", "\n", @@ -5130,7 +1008,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -5139,28 +1017,6 @@ "metadata": {}, "output_type": "display_data" }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[381]-tess.flux[387],vmax=5,vmin=-5)" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "ffed84cf", - "metadata": {}, - "outputs": [ { "data": { "application/javascript": [ @@ -5358,15 +1214,6 @@ " }\n", "\n", " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\n", " var nentries = entries.length;\n", " for (var i = 0; i < nentries; i++) {\n", " var entry = entries[i];\n", @@ -5414,7 +1261,7 @@ " // 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 (width != 0 && height != 0) {\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", " fig.request_resize(width, height);\n", " }\n", " }\n", @@ -5763,22 +1610,6 @@ " };\n", "};\n", "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", "\n", "/*\n", " * return a copy of an object with only non-object keys\n", @@ -5810,7 +1641,6 @@ " y: y,\n", " button: event.button,\n", " step: event.step,\n", - " modifiers: getModifiers(event),\n", " guiEvent: simpleKeys(event),\n", " });\n", "\n", @@ -6158,7 +1988,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -6167,40 +1997,6 @@ "metadata": {}, "output_type": "display_data" }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[381],vmax=5,vmin=-5)" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "eae84ba5", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "made source mask\n", - "calculating background\n", - "background subtracted\n", - "field calibration\n", - "target is above -30 dec, calibrating to PS1 photometry.\n" - ] - }, { "data": { "application/javascript": [ @@ -6398,15 +2194,6 @@ " }\n", "\n", " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\n", " var nentries = entries.length;\n", " for (var i = 0; i < nentries; i++) {\n", " var entry = entries[i];\n", @@ -6454,7 +2241,7 @@ " // 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 (width != 0 && height != 0) {\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", " fig.request_resize(width, height);\n", " }\n", " }\n", @@ -6803,22 +2590,6 @@ " };\n", "};\n", "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", "\n", "/*\n", " * return a copy of an object with only non-object keys\n", @@ -6850,7 +2621,6 @@ " y: y,\n", " button: event.button,\n", " step: event.step,\n", - " modifiers: getModifiers(event),\n", " guiEvent: simpleKeys(event),\n", " });\n", "\n", @@ -7198,7 +2968,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -7206,90 +2976,7 @@ }, "metadata": {}, "output_type": "display_data" - } - ], - "source": [ - "tess = tr.tessreduce(tpf='../../SN_individual/2020ghq/s23.fits',reduce=True,plot=True,diff=False,align=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "8515649f", - "metadata": {}, - "outputs": [], - "source": [ - "from scipy.optimize import minimize\n", - "from scipy import signal\n", - "from astropy.convolution import Gaussian2DKernel\n", - "\n", - "from scipy.optimize import minimize\n", - "\n", - "def Delta_basis(Size = 13):\n", - " kernal = np.zeros((Size,Size))\n", - " x,y = np.where(kernal==0)\n", - " middle = int(len(x)/2)\n", - " basis = []\n", - " for i in range(len(x)):\n", - " b = kernal.copy()\n", - " if (x[i] == x[middle]) & (y[i] == y[middle]):\n", - " b[x[i],y[i]] = 1\n", - " else:\n", - " b[x[i],y[i]] = 1\n", - " b[x[middle],y[middle]] = -1\n", - " basis += [b]\n", - " basis = np.array(basis)\n", - " coeff = np.ones(len(basis))\n", - " return basis, coeff\n", - "\n", - "def Delta_kernal(Scene,Image,Size=7,mask=None):\n", - " if mask is None:\n", - " mask = np.ones_like(Image)\n", - " mask[mask == 0] = np.nan\n", - " Basis, coeff_0 = Delta_basis(Size)\n", - " bds = []\n", - " for i in range(len(coeff_0)):\n", - " bds += [(0,1)]\n", - " coeff_0 *= 0.01\n", - " coeff_0[Size//2+1] = 0.95\n", - " res = minimize(optimize_delta, coeff_0, args=(Basis,Scene,Image,Size,mask),\n", - " bounds=bds,method='Powell')\n", - " k = np.nansum(res.x[:,np.newaxis,np.newaxis]*Basis,axis=0)\n", - " return k\n", - " \n", - "def optimize_delta(Coeff, Basis, Scene, Image,size,mask):\n", - " Kernal = np.nansum(Coeff[:,np.newaxis,np.newaxis]*Basis,axis=0)\n", - "\n", - " template = signal.fftconvolve(Scene, Kernal, mode='same')\n", - " \n", - " im = Image.copy()\n", - " \n", - " res = np.nansum(abs(im[size//2:-size//2,size//2:-size//2]-template[size//2:-size//2,size//2:-size//2])*mask[size//2:-size//2,size//2:-size//2])\n", - " #print(res)\n", - " return res\n", - " \n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 86, - "id": "65bc9147", - "metadata": {}, - "outputs": [], - "source": [ - "ind = 381\n", - "flux = tess.flux\n", - "k = Delta_kernal(flux[tess.ref_ind],flux[ind],Size=9,mask=tess.mask==1)\n", - "template = signal.fftconvolve(flux[tess.ref_ind], k, mode='same')" - ] - }, - { - "cell_type": "code", - "execution_count": 88, - "id": "4a67fb64", - "metadata": {}, - "outputs": [ + }, { "data": { "application/javascript": [ @@ -7487,15 +3174,6 @@ " }\n", "\n", " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\n", " var nentries = entries.length;\n", " for (var i = 0; i < nentries; i++) {\n", " var entry = entries[i];\n", @@ -7543,7 +3221,7 @@ " // 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 (width != 0 && height != 0) {\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", " fig.request_resize(width, height);\n", " }\n", " }\n", @@ -7892,22 +3570,6 @@ " };\n", "};\n", "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", "\n", "/*\n", " * return a copy of an object with only non-object keys\n", @@ -7939,7 +3601,6 @@ " y: y,\n", " button: event.button,\n", " step: event.step,\n", - " modifiers: getModifiers(event),\n", " guiEvent: simpleKeys(event),\n", " });\n", "\n", @@ -8287,7 +3948,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -8295,67 +3956,34 @@ }, "metadata": {}, "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 88, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "ind = 381\n", - "flux = tess.flux\n", - "k = Delta_kernal(flux[tess.ref_ind],flux[ind],Size=9,mask=tess.mask==1)\n", - "template = signal.fftconvolve(flux[tess.ref_ind], k, mode='same')\n", - "plt.figure()\n", - "plt.imshow(flux[ind]- template,vmax=5,vmin=-5)" + "tess = tr.tessreduce(tpf='../../SN_individual/2020ghq/s23.fits',reduce=True,plot=True,diff=False,align=False)" ] }, { "cell_type": "code", - "execution_count": 4, - "id": "d081b80b", + "execution_count": 59, + "id": "ec563803", "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'tess' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[4], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m ind \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m365\u001b[39m\n\u001b[1;32m 2\u001b[0m flux \u001b[38;5;241m=\u001b[39m tessa\u001b[38;5;241m.\u001b[39mflux \u001b[38;5;241m+\u001b[39m tessa\u001b[38;5;241m.\u001b[39mref\n\u001b[0;32m----> 3\u001b[0m k \u001b[38;5;241m=\u001b[39m Delta_kernal(flux[tessa\u001b[38;5;241m.\u001b[39mref_ind],flux[ind],Size\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m11\u001b[39m,mask\u001b[38;5;241m=\u001b[39m\u001b[43mtess\u001b[49m\u001b[38;5;241m.\u001b[39mmask\u001b[38;5;241m==\u001b[39m\u001b[38;5;241m1\u001b[39m)\n\u001b[1;32m 4\u001b[0m template \u001b[38;5;241m=\u001b[39m signal\u001b[38;5;241m.\u001b[39mfftconvolve(tessa\u001b[38;5;241m.\u001b[39mref, k, mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124msame\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 6\u001b[0m \u001b[38;5;66;03m#k2 = Delta_kernal(flux[ind],flux[tessa.ref_ind],Size=9,mask=tess.mask==1)\u001b[39;00m\n\u001b[1;32m 7\u001b[0m \u001b[38;5;66;03m#matched = signal.fftconvolve(flux[ind], k2, mode='same')\u001b[39;00m\n", - "\u001b[0;31mNameError\u001b[0m: name 'tess' is not defined" - ] - } - ], + "outputs": [], "source": [ - "ind = 365\n", - "flux = tessa.flux + tessa.ref\n", - "k = Delta_kernal(flux[tessa.ref_ind],flux[ind],Size=11,mask=tess.mask==1)\n", - "template = signal.fftconvolve(tessa.ref, k, mode='same')\n", - "\n", - "#k2 = Delta_kernal(flux[ind],flux[tessa.ref_ind],Size=9,mask=tess.mask==1)\n", - "#matched = signal.fftconvolve(flux[ind], k2, mode='same')\n", - "\n", - "plt.figure(figsize=(8,4))\n", - "plt.subplot(121)\n", - "plt.imshow(tessa.flux[ind],vmax=5,vmin=-5)\n", - "plt.subplot(122)\n", - "plt.imshow(flux[ind] - template,vmax=5,vmin=-5)\n", - "#plt.subplot(133)\n", - "#plt.imshow(matched - flux[tessa.ref_ind],vmax=5,vmin=-5)" + "align, footprint = aa.register(tess.flux[100],tess.ref,max_control_points=10,detection_sigma=3)" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "08e544dc", + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": 11, - "id": "904f199b", + "id": "29ebe6f9", "metadata": {}, "outputs": [], "source": [ @@ -8365,7 +3993,7 @@ { "cell_type": "code", "execution_count": 14, - "id": "d711e22c", + "id": "959f361e", "metadata": {}, "outputs": [], "source": [ @@ -8377,7 +4005,7 @@ { "cell_type": "code", "execution_count": 22, - "id": "a176bb7f", + "id": "5decada4", "metadata": {}, "outputs": [ { @@ -9382,7 +5010,7 @@ { "cell_type": "code", "execution_count": 61, - "id": "63e973cc", + "id": "2b9c3bed", "metadata": {}, "outputs": [], "source": [ @@ -9393,7 +5021,7 @@ { "cell_type": "code", "execution_count": 78, - "id": "6f50f5ce", + "id": "c1bbafd0", "metadata": {}, "outputs": [], "source": [ @@ -9404,7 +5032,7 @@ { "cell_type": "code", "execution_count": 79, - "id": "0970f406", + "id": "d4273ca6", "metadata": {}, "outputs": [], "source": [] @@ -9412,7 +5040,7 @@ { "cell_type": "code", "execution_count": 80, - "id": "ce596ac8", + "id": "62daf0d2", "metadata": {}, "outputs": [], "source": [ @@ -9423,7 +5051,7 @@ { "cell_type": "code", "execution_count": null, - "id": "2a315baf", + "id": "c7fd0dde", "metadata": {}, "outputs": [], "source": [ @@ -9433,7 +5061,7 @@ { "cell_type": "code", "execution_count": 28, - "id": "2c6d16aa", + "id": "ae95b4cc", "metadata": {}, "outputs": [], "source": [ @@ -9444,7 +5072,7 @@ { "cell_type": "code", "execution_count": 34, - "id": "6bbf1eeb", + "id": "e71f6464", "metadata": {}, "outputs": [], "source": [ @@ -9454,8 +5082,8 @@ }, { "cell_type": "code", - "execution_count": 109, - "id": "0fc73129", + "execution_count": 33, + "id": "8ddf00f3", "metadata": {}, "outputs": [ { @@ -9655,15 +5283,6 @@ " }\n", "\n", " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\n", " var nentries = entries.length;\n", " for (var i = 0; i < nentries; i++) {\n", " var entry = entries[i];\n", @@ -9711,7 +5330,7 @@ " // 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 (width != 0 && height != 0) {\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", " fig.request_resize(width, height);\n", " }\n", " }\n", @@ -10060,22 +5679,6 @@ " };\n", "};\n", "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", "\n", "/*\n", " * return a copy of an object with only non-object keys\n", @@ -10107,7 +5710,6 @@ " y: y,\n", " button: event.button,\n", " step: event.step,\n", - " modifiers: getModifiers(event),\n", " guiEvent: simpleKeys(event),\n", " });\n", "\n", @@ -10455,7 +6057,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -10467,23 +6069,23 @@ { "data": { "text/plain": [ - "[]" + "" ] }, - "execution_count": 109, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plt.figure()\n", - "plt.plot(tessa.lc[1])" + "plt.imshow(thing)" ] }, { "cell_type": "code", "execution_count": 87, - "id": "b2808073", + "id": "bedd311c", "metadata": {}, "outputs": [], "source": [ @@ -10501,7 +6103,7 @@ { "cell_type": "code", "execution_count": 89, - "id": "a8f4b53c", + "id": "cfe80950", "metadata": {}, "outputs": [ { @@ -11507,7 +7109,7 @@ { "cell_type": "code", "execution_count": 37, - "id": "b1fe6f89", + "id": "cc99c563", "metadata": {}, "outputs": [ { @@ -11566,7 +7168,7 @@ { "cell_type": "code", "execution_count": null, - "id": "3cd70e72", + "id": "2889a724", "metadata": {}, "outputs": [], "source": [] diff --git a/development/straps.ipynb b/development/straps.ipynb index 3ef111c..8b5cbc3 100755 --- a/development/straps.ipynb +++ b/development/straps.ipynb @@ -2,8 +2,8 @@ "cells": [ { "cell_type": "code", - "execution_count": 4, - "id": "7b7acf36", + "execution_count": 3, + "id": "korean-moment", "metadata": {}, "outputs": [], "source": [ @@ -16,30486 +16,64 @@ }, { "cell_type": "code", - "execution_count": 6, - "id": "db7fdddc", + "execution_count": 4, + "id": "organized-fetish", "metadata": {}, "outputs": [], "source": [ - "tess = tr.tessreduce(tpf='/Users/rri38/Documents/work/data/tess/tessellate_test/sector34_cam1_ccd4_cut23_of64.fits',\n", - " calibrate=False,reduce=False,align=True)\n" + "ra = 269.0488792\n", + "dec = 62.75700278\n", + "sector = 21\n", + "size = 90" ] }, { "cell_type": "code", - "execution_count": 9, - "id": "c4f3a510", + "execution_count": 5, + "id": "expired-traffic", + "metadata": {}, + "outputs": [], + "source": [ + "tess = tr.tessreduce(ra=ra,dec=dec,size=size,sector=sector)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "international-level", "metadata": {}, "outputs": [ { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[100],vmax=200)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "9ed0ef8d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", - "made source mask\n", - "calculating background\n", - "background subtracted\n", - "aligning images\n", - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n", - "background correlation correction\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# tess = tr.tessreduce(ra=ra,dec=dec,size=size,sector=sector)\n", - "tess = tr.tessreduce(tpf='../../SN_individual/grb_test.fits',calibrate=False,reduce=True,align=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "d2a45d04", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.qe[10])" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "f81ed34a", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.qe[:,0,21])" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "fd4036ce", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[2000],vmax=200)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "b6247a62", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "(array([[ 5.92282592e+04, 5.92282662e+04, 5.92282731e+04, ...,\n", - " 5.92535506e+04, 5.92535576e+04, 5.92535645e+04],\n", - " [ 3.67880034e+00, 3.36370429e+00, 2.36528889e+00, ...,\n", - " -9.43662369e-01, 3.62235021e-01, 1.07290616e+00],\n", - " [ 1.96582265e+01, 2.83868966e+01, 1.54534967e+01, ...,\n", - " 5.68223188e+00, 4.10522619e+00, 7.43495942e+00]]),\n", - " array([[ 5.92282592e+04, 5.92282662e+04, 5.92282731e+04, ...,\n", - " 5.92535506e+04, 5.92535576e+04, 5.92535645e+04],\n", - " [-1.72890912e-01, -4.63733754e-01, 5.74060295e-01, ...,\n", - " 3.41624312e-01, -1.30153295e-01, -1.20709109e-01],\n", - " [ 2.18424739e+00, 3.15409962e+00, 1.71705519e+00, ...,\n", - " 6.31359097e-01, 4.56136243e-01, 8.26106602e-01]]))" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.diff_lc(x=10,y=25,plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "2d3abafc", - "metadata": {}, - "outputs": [], - "source": [ - "ra = 269.0488792\n", - "dec = 62.75700278\n", - "sector = 21\n", - "size = 90" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "db053c1c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", - "made source mask\n", - "calculating background\n", - "background subtracted\n", - "aligning images\n", - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n", - "background correlation correction\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "72341c3b", - "metadata": {}, - "outputs": [], - "source": [ - "plt." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "29fd8148", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "-15.735450744628906" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.nanmin(tess.ref)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "187d279e", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.qe[10])" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "bfc1b839", - "metadata": {}, - "outputs": [], - "source": [ - "mask = tess.mask & 1" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "126a1784", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "bdf60994", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "j = 100\n", - "test = np.nanmedian(tess.flux[j]+tess.bkg[j])\n", - "plt.figure()\n", - "plt.imshow((tess.flux[j]+tess.bkg[j]-test),vmax=20,vmin=-20)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "417eb793", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow((tess.flux[j]),vmax=20,vmin=-20)" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "d20668bc", - "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)", - "Cell \u001b[0;32mIn[1], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mplt\u001b[49m\u001b[38;5;241m.\u001b[39mfigure()\n\u001b[1;32m 2\u001b[0m plt\u001b[38;5;241m.\u001b[39mimshow(tess\u001b[38;5;241m.\u001b[39mflux[\u001b[38;5;241m3000\u001b[39m])\n", - "\u001b[0;31mNameError\u001b[0m: name 'plt' is not defined" - ] - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[3000])" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "66e8f6de", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "(array([[ 5.92282592e+04, 5.92282662e+04, 5.92282731e+04, ...,\n", - " 5.92535506e+04, 5.92535576e+04, 5.92535645e+04],\n", - " [-2.96795470e+01, -1.88339220e+01, -1.86687968e+01, ...,\n", - " 1.03656914e+01, 5.47651041e+00, 5.10114870e+00],\n", - " [ 9.10676154e-02, 1.04193665e+00, 6.12205259e-02, ...,\n", - " 2.11130854e+00, 9.59214808e-03, 2.12665321e+00]]),\n", - " array([[ 5.92282592e+04, 5.92282662e+04, 5.92282731e+04, ...,\n", - " 5.92535506e+04, 5.92535576e+04, 5.92535645e+04],\n", - " [ 3.63534568e-01, 8.44251888e-01, 1.31115982e+00, ...,\n", - " -1.01069135e+00, -5.10593418e-01, -3.58591887e-01],\n", - " [ 5.86976890e+00, 5.14894084e+00, 5.24861637e+00, ...,\n", - " 4.54362577e+00, 4.35464453e+00, 4.44011973e+00]]))" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.diff_lc(phot_method='psf',plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "97d69388", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "made source mask\n" - ] - } - ], - "source": [ - "tess.get_ref()\n", - "tess.ref -= np.nanmin(tess.ref)\n", - "if tess.verbose > 0:\n", - " print('made reference')\n", - "# make source mask\n", - "# tess.make_mask(maglim=18,strapsize=7,scale=1)#Source_mask(ref,grid=0)\n", - "# frac = np.nansum((tess.mask == 0) * 1.) / (tess.mask.shape[0] * tess.mask.shape[1])\n", - "# print('mask frac ',frac)\n", - "# if frac < 0.2:\n", - "# print('!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.')\n", - "tess.make_mask(maglim=15,strapsize=7,scale=0.5)\n", - "if tess.verbose > 0:\n", - " print('made source mask')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3f74fcc2", - "metadata": {}, - "outputs": [], - "source": [ - "te" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "9166f821", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.mask)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "7d5306ec", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow((tess.ref)*(~tess.mask&1),vmax=50)" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "1070c098", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow((tess.flux[10]-tess.ref)*((tess.mask&4) > 0)*(~tess.mask&1),vmin=1000,vmax=1300)" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "aa412882", - "metadata": {}, - "outputs": [], - "source": [ - "from tessreduce.helpers import *" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "2b262fba", - "metadata": {}, - "outputs": [], - "source": [ - "interpolate = False\n", - "gauss_smooth = 2\n", - "qes = np.ones_like(tess.flux)\n", - "bkg = np.ones_like(tess.flux)\n", - "\n", - "for i in range(len(tess.flux)):\n", - " data = (tess.flux[i]-tess.ref)*(~(tess.mask>0))\n", - " data[data==0] = np.nan\n", - "\n", - " x = np.arange(0, data.shape[1])\n", - " y = np.arange(0, data.shape[0])\n", - " arr = np.ma.masked_invalid(deepcopy(data))\n", - " xx, yy = np.meshgrid(x, y)\n", - " #get only the valid values\n", - " x1 = xx[~arr.mask]\n", - " y1 = yy[~arr.mask]\n", - " newarr = arr[~arr.mask]\n", - " if (len(x1) > 10) & (len(y1) > 10):\n", - " if interpolate:\n", - " estimate = griddata((x1, y1), newarr.ravel(),\n", - " (xx, yy),method='linear')\n", - " nearest = griddata((x1, y1), newarr.ravel(),\n", - " (xx, yy),method='nearest')\n", - " if extrapolate:\n", - " estimate[np.isnan(estimate)] = nearest[np.isnan(estimate)]\n", - "\n", - " estimate = gaussian_filter(estimate,gauss_smooth)\n", - "\n", - " #estimate = median_filter(estimate,5)\n", - " else:\n", - " # try inpaint stuff \n", - " mask = deepcopy(arr.mask)\n", - " mask = mask.astype(bool)\n", - " # end inpaint\n", - " estimate = inpaint.inpaint_biharmonic(data,mask)\n", - " #estimate = signal.fftconvolve(estimate,self.prf,mode='same')\n", - " if (np.nanmedian(estimate) < 100) & (np.nanstd(estimate) < 3): # magic numbers to define a well behaved background\n", - " gauss_smooth = gauss_smooth * 3\n", - " estimate = gaussian_filter(estimate,gauss_smooth)\n", - " \n", - " strap_data = (tess.flux[i]-tess.ref) * ((tess.mask&4) > 0)*(~tess.mask&1)\n", - " qe = (strap_data)/estimate\n", - " qe[qe==0]= np.nan\n", - "\n", - " m,med,std = sigma_clipped_stats(qe,axis=0,sigma_upper=2,sigma_lower=10)\n", - "\n", - " q = np.ones_like(strap_data)\n", - " q[:] = med\n", - " q[np.isnan(q)] = 1\n", - " qes[i] = q\n", - " bkg[i] = estimate" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "id": "7a00b622", - "metadata": {}, - "outputs": [], - "source": [ - "strap_data = (tess.flux-tess.ref) * ((tess.mask&4) > 0)*(~tess.mask&1)\n", - "rqe = (strap_data)/bkg\n", - "rqe[rqe==0] = np.nan" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "22afb5a3", - "metadata": {}, - "outputs": [], - "source": [ - "strap_data = (tess.flux) * ((tess.mask&4) > 0)*(~tess.mask&1)\n", - "qe = (strap_data)/bkg\n", - "qe[qe==0] = np.nan" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "id": "22dbf65f", - "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_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure()\n", - "bins = np.logspace(np.log10(.01), np.log10(tess.ref.max()), 50)\n", - "\n", - "plt.hist(tess.ref.flatten(), bins=bins)\n", - "plt.xscale('log')" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "811d458f", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[100])" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "id": "b195c872", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(bkg[10])\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "id": "26983a2d", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 56, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.subplot(121)\n", - "plt.imshow(rqe[10],vmin=1)\n", - "plt.subplot(122)\n", - "plt.imshow(qe[10],vmin=1)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "7da32763", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure()\n", - "plt.subplot(121)\n", - "for i in range(50):\n", - " plt.plot(rqe[1,:,i],'.')\n", - "plt.subplot(122)\n", - "for i in range(50):\n", - " plt.plot(qe[1,:,i],'.')" - ] - }, - { - "cell_type": "code", - "execution_count": 400, - "id": "339d9600", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([1. , 1. , 1. , 1. , 1. ,\n", - " 1. , 1. , 1. , 1. , 1. ,\n", - " 1. , 1. , 1. , 1. , 1. ,\n", - " 1. , 1. , 1. , 1.0033444 , 1.0091093 ,\n", - " 1.030537 , 1.0727113 , 1.0667713 , 1.026451 , 1.0349513 ,\n", - " 1.072208 , 1.0637119 , 1.0232186 , 1.0317849 , 1.0683197 ,\n", - " 1.0614612 , 1.0143926 , 1.0021496 , 0.99974775, 1. ,\n", - " 1. , 1. , 1. , 1. , 1. ,\n", - " 1. , 1. , 1. , 1. , 1. ,\n", - " 1. , 1. , 1. , 1. , 1. ],\n", - " dtype=float32)" - ] - }, - "execution_count": 400, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "m,med,std = sigma_clipped_stats(qes,axis=1,sigma_upper=2,sigma_lower=10)\n", - "med[10]" - ] - }, - { - "cell_type": "code", - "execution_count": 401, - "id": "5cd54475", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([1. , 1. , 1. , 1. , 1. ,\n", - " 1. , 1. , 1. , 1. , 1. ,\n", - " 1. , 1. , 1. , 1. , 1. ,\n", - " 1. , 1. , 1. , 1.0033444 , 1.0091093 ,\n", - " 1.030537 , 1.0727113 , 1.0667713 , 1.026451 , 1.0349513 ,\n", - " 1.072208 , 1.0637119 , 1.0232186 , 1.0317849 , 1.0683197 ,\n", - " 1.0614612 , 1.0143926 , 1.0021496 , 0.99974775, 1. ,\n", - " 1. , 1. , 1. , 1. , 1. ,\n", - " 1. , 1. , 1. , 1. , 1. ,\n", - " 1. , 1. , 1. , 1. , 1. ],\n", - " dtype=float32)" - ] - }, - "execution_count": 401, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "m,med,std = sigma_clipped_stats(qes[10],axis=0,sigma_upper=2,sigma_lower=10)\n", - "med" - ] - }, - { - "cell_type": "code", - "execution_count": 412, - "id": "4e01b336", - "metadata": {}, - "outputs": [], - "source": [ - "tess.ref -= np.nanmin(tess.ref)" - ] - }, - { - "cell_type": "code", - "execution_count": 440, - "id": "e725cbb5", - "metadata": {}, - "outputs": [], - "source": [ - "def calc_qe(self):\n", - " strap_data = (self.flux-self.ref) * ((self.mask&4) > 0)*(~self.mask&1)\n", - " qe = strap_data/self.bkg\n", - " qe[qe == 0] = np.nan\n", - " m,med,std = sigma_clipped_stats(qe,axis=1,sigma_upper=2)\n", - " qes = np.ones_like(qe)\n", - " qes[:,:,:] = med[:,np.newaxis,:]\n", - " qes[np.isnan(qes)] = 1\n", - " \n", - " av_bkg = np.sum(self.bkg,axis=(1,2))/(self.bkg.shape[1]*self.bkg.shape[2])\n", - " ind = av_bkg < np.nanmean(av_bkg)\n", - " breaks = np.where(np.diff(time[ind]) > 0.5)[0]+1\n", - " breaks = np.insert(breaks, 0, 0)\n", - " breaks = np.append(breaks, len(time[ind]))\n", - " \n", - " new_qes = deepcopy(qes)\n", - " ind_where = np.where(ind)[0]\n", - " for i in range(len(breaks)-1):\n", - " window_size = int(abs(breaks[i]-breaks[i+1])/4)\n", - " if window_size/2 == window_size//2:\n", - " window_size += 1\n", - " print(window_size)\n", - " #if window_size > abs(breaks[i]-breaks[i+1])/4:\n", - "\n", - " seg_idx = ind_where[breaks[i]:breaks[i+1]]\n", - " sav = savgol_filter(qes[ind][breaks[i]:breaks[i+1]], window_size, 1, axis=0)\n", - " new_qes[seg_idx] = sav\n", - " new_qes[new_qes < 1.005] = 1 # set a limit of 1% adjustment \n", - " self.qe = new_qes" - ] - }, - { - "cell_type": "code", - "execution_count": 441, - "id": "76105430", - "metadata": {}, - "outputs": [], - "source": [ - "tess.bkg = bkg" - ] - }, - { - "cell_type": "code", - "execution_count": 442, - "id": "1937d7dc", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "421\n", - "415\n" - ] - } - ], - "source": [ - "calc_qe(tess)" - ] - }, - { - "cell_type": "code", - "execution_count": 444, - "id": "ac4b0f97", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 444, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.qe[1755])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f2b6162c", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 237, - "id": "40ea7076", - "metadata": {}, - "outputs": [], - "source": [ - "i = 200\n", - "strap_data = (tess.flux[i]-tess.ref) * ((tess.mask&4) > 0)*(~tess.mask&1)\n", - "qe = (strap_data)/bkg[i]\n", - "qe[qe==0] = np.nan" - ] - }, - { - "cell_type": "code", - "execution_count": 238, - "id": "444a7430", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 238, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(qe[:,22])" - ] - }, - { - "cell_type": "code", - "execution_count": 157, - "id": "f311d260", - "metadata": {}, - "outputs": [], - "source": [ - "m,med,std = sigma_clipped_stats(bkg,axis=(1,2))" - ] - }, - { - "cell_type": "code", - "execution_count": 158, - "id": "e539a7c3", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 158, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(med)" - ] - }, - { - "cell_type": "code", - "execution_count": 179, - "id": "629c0474", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[0., 0., 0., ..., 0., 0., 0.],\n", - " [0., 0., 0., ..., 0., 0., 0.],\n", - " [0., 0., 0., ..., 0., 0., 0.],\n", - " ...,\n", - " [0., 0., 0., ..., 0., 0., 0.],\n", - " [0., 0., 0., ..., 0., 0., 0.],\n", - " [0., 0., 0., ..., 0., 0., 0.]], dtype=float32)" - ] - }, - "execution_count": 179, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "qes[1900]*bkg[1900]- bkg[1900]" - ] - }, - { - "cell_type": "code", - "execution_count": 422, - "id": "dffc8bc8", - "metadata": {}, - "outputs": [], - "source": [ - "grad = np.gradient(np.sum(bkg,axis=(1,2)),tess.mjd) # not sure about this gradient \n", - "time = deepcopy(tess.mjd)\n", - "m,med,std = sigma_clipped_stats(abs(grad))\n", - "ind = abs(grad) < (med + 15*std)\n", - "av_bkg = np.sum(bkg,axis=(1,2))/(bkg.shape[1]*bkg.shape[2])\n", - "ind = av_bkg < np.nanmean(av_bkg)\n", - "breaks = np.where(np.diff(time[ind]) > 0.5)[0]+1\n", - "breaks = np.insert(breaks, 0, 0)\n", - "breaks = np.append(breaks, len(time[ind]))" - ] - }, - { - "cell_type": "code", - "execution_count": 423, - "id": "a71e46e3", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "421\n", - "415\n" - ] - } - ], - "source": [ - "new_qes = deepcopy(qes)\n", - "ind_where = np.where(ind)[0]\n", - "for i in range(len(breaks)-1):\n", - " window_size = int(abs(breaks[i]-breaks[i+1])/4)\n", - " if window_size/2 == window_size//2:\n", - " window_size += 1\n", - " print(window_size)\n", - " #if window_size > abs(breaks[i]-breaks[i+1])/4:\n", - " \n", - " seg_idx = ind_where[breaks[i]:breaks[i+1]]\n", - " sav = savgol_filter(qes[ind][breaks[i]:breaks[i+1]], window_size, 1, axis=0)\n", - " new_qes[seg_idx] = sav\n", - "new_qes[new_qes < 1.001] = 1 # set a limit of 1% adjustment " - ] - }, - { - "cell_type": "code", - "execution_count": 424, - "id": "889c5668", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 424, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(av_bkg)\n", - "plt.axhline(np.nanmean(av_bkg))" - ] - }, - { - "cell_type": "code", - "execution_count": 425, - "id": "f5e503cb", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 425, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "av_bkg = np.sum(bkg,axis=(1,2))/50**2\n", - "av_bkg = av_bkg / np.nanmax(av_bkg) + 1\n", - "\n", - "plt.figure(np.nanmean(av_bkg))\n", - "#for i in range(1):# len(qes)):\n", - "plt.plot(qes[:,0,26])\n", - "plt.plot(new_qes[:,0,26])\n", - "#plt.plot(av_bkg)\n", - "#plt.plot(qes[:,0,22])\n", - "#plt.plot(qes[:,0,19])\n", - "#plt.plot(qes[:,0,18])" - ] - }, - { - "cell_type": "code", - "execution_count": 334, - "id": "3556c553", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([2717.0503 , 2487.0432 , 2279.232 , ..., 115.25409, 115.15603,\n", - " 115.25877], dtype=float32)" - ] - }, - "execution_count": 334, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.sum(bkg,axis=(1,2))/50**2" - ] - }, - { - "cell_type": "code", - "execution_count": 364, - "id": "e60bf638", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 364, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "j = 1760\n", - "plt.figure()\n", - "plt.subplot(121)\n", - "plt.imshow(qes[j])\n", - "plt.subplot(122)\n", - "plt.imshow(new_qes[j])" - ] - }, - { - "cell_type": "code", - "execution_count": 251, - "id": "9fb221c5", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 251, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "j = 10\n", - "plt.figure()\n", - "plt.imshow(test[j]/test[1750])\n", - "plt.colorbar()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ea05ebba", - "metadata": {}, - "outputs": [], - "source": [ - "qes[j]*bkg[j]- bkg[j]" - ] - }, - { - "cell_type": "code", - "execution_count": 261, - "id": "43dfb3fb", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 261, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "j = 1750\n", - "plt.figure()\n", - "plt.imshow(qes[j]*bkg[j])\n", - "plt.colorbar()" - ] - }, - { - "cell_type": "code", - "execution_count": 365, - "id": "651c7c41", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 365, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.subplot(131)\n", - "plt.imshow(bkg[j])\n", - "plt.subplot(132)\n", - "plt.imshow(new_qes[j])\n", - "plt.subplot(133)\n", - "plt.imshow(new_qes[j]*bkg[j])\n", - "#plt.colorbar()" - ] - }, - { - "cell_type": "code", - "execution_count": 445, - "id": "cfa08166", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "Text(0.5, 1.0, 'Subtrated')" - ] - }, - "execution_count": 445, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n", + "made reference\n", + "mask frac 0.08358024691358025\n", + "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", + "made source mask\n" + ] } ], "source": [ - "j = 1760\n", - "plt.figure()\n", - "plt.subplot(131)\n", - "plt.imshow(tess.flux[j],vmax=2000,origin='lower')\n", - "plt.title('Raw image')\n", - "plt.subplot(132)\n", - "plt.imshow(bkg[j]*new_qes[j],vmax=2000,origin='lower')\n", - "plt.title('Strap background')\n", - "plt.subplot(133)\n", - "plt.imshow(tess.flux[j]/new_qes[j]-bkg[j],vmax=450,origin='lower')\n", - "plt.title('Subtrated')" + "tess.get_ref()\n", + "if tess.verbose > 0:\n", + " print('made reference')\n", + "# make source mask\n", + "tess.Make_mask(maglim=18,strapsize=4,scale=1)#Source_mask(ref,grid=0)\n", + "frac = np.nansum((tess.mask == 0) * 1.) / (tess.mask.shape[0] * tess.mask.shape[1])\n", + "print('mask frac ',frac)\n", + "if frac < 0.2:\n", + " print('!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.')\n", + " tess.Make_mask(maglim=15,strapsize=4,scale=0.5)\n", + "if tess.verbose > 0:\n", + " print('made source mask')" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "eeb3accd", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 9, - "id": "94909c76", + "id": "capable-guest", "metadata": {}, "outputs": [], "source": [ @@ -30521,7 +99,7 @@ { "cell_type": "code", "execution_count": 13, - "id": "614be81c", + "id": "placed-measurement", "metadata": {}, "outputs": [ { @@ -31500,7 +1078,7 @@ { "cell_type": "code", "execution_count": 23, - "id": "9040d6f4", + "id": "realistic-compound", "metadata": {}, "outputs": [], "source": [ @@ -31510,7 +1088,7 @@ { "cell_type": "code", "execution_count": 21, - "id": "27acfb5e", + "id": "apparent-village", "metadata": {}, "outputs": [ { @@ -31537,7 +1115,7 @@ { "cell_type": "code", "execution_count": 35, - "id": "f5b79e05", + "id": "attractive-spotlight", "metadata": {}, "outputs": [ { @@ -33470,7 +3048,7 @@ { "cell_type": "code", "execution_count": 34, - "id": "c3b1de81", + "id": "surface-mathematics", "metadata": {}, "outputs": [], "source": [ @@ -33492,7 +3070,7 @@ { "cell_type": "code", "execution_count": 29, - "id": "7537c125", + "id": "unusual-video", "metadata": {}, "outputs": [ { @@ -33519,7 +3097,7 @@ { "cell_type": "code", "execution_count": null, - "id": "446f4d59", + "id": "scientific-dubai", "metadata": {}, "outputs": [], "source": [] @@ -33527,7 +3105,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -33541,7 +3119,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.2" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/development/svs1755clustering_example.pdf b/development/svs1755clustering_example.pdf new file mode 100755 index 0000000..f375ae8 Binary files /dev/null and b/development/svs1755clustering_example.pdf differ diff --git a/development/svs1755clustering_example.png b/development/svs1755clustering_example.png new file mode 100755 index 0000000..3659cc8 Binary files /dev/null and b/development/svs1755clustering_example.png differ diff --git a/development/temporal_smoothing_background.ipynb b/development/temporal_smoothing_background.ipynb deleted file mode 100644 index 4f94de7..0000000 --- a/development/temporal_smoothing_background.ipynb +++ /dev/null @@ -1,49736 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "b5ab3286", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import tessreduce as tr\n", - "%matplotlib notebook" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "62bd5b31", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", - "made source mask\n", - "calculating background\n", - "adaptive bkg\n", - "background subtracted\n", - "aligning images\n", - "!!!WARNING!!! 3372 frame(s) had fewer than 10 sources — source-pixel alignment used as fallback.\n", - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n", - "adaptive bkg\n", - "background correlation correction\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess = tr.tessreduce(tpf='../../SN_individual/grb_test.fits',\n", - " calibrate=False,quality_bitmask='hard',reduce=True,diff=True,align=True,\n", - " shift_method='sep_core')\n", - "# np.save('test_bkg2.npy',tess.bkg)\n", - "# np.save('test_bkg2_time.npy',tess.mjd)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "e67f33e6", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.bkg[2850])" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "5085119b", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.bkg[:,25,25])\n", - "plt.plot(tess.bkg[:,24,24])" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "44d4920c", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.flux[:,22,14])\n", - "plt.plot(tess.bkg[:,22,14]-120)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "12ba1f79", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.tpf.camera" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "5b952190", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.tpf.ccd" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "660c638b", - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", - "made source mask\n", - "calculating background\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "background subtracted\n", - "aligning images\n", - "!!!WARNING!!! 3372 frame(s) had fewer than 10 sources — source-pixel alignment used as fallback.\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "--- Source quality table ---\n", - " x (px) y (px) peak flux In bounds Round Unflagged Unsaturated Not masked Overall\n", - "ID \n", - "0 37.20 0.36 365.4 1190.4 FAIL PASS FAIL PASS PASS FAIL\n", - "1 41.68 0.73 712.1 3339.5 FAIL PASS FAIL PASS PASS FAIL\n", - "2 10.11 1.04 350.5 1203.9 FAIL PASS FAIL PASS PASS FAIL\n", - "3 0.29 3.83 230.0 473.9 FAIL PASS FAIL PASS PASS FAIL\n", - "4 48.47 4.44 109.8 302.4 FAIL PASS FAIL PASS PASS FAIL\n", - "5 2.19 8.86 135.4 547.7 FAIL PASS PASS PASS PASS FAIL\n", - "6 24.61 6.58 593.6 4610.3 PASS PASS PASS PASS FAIL FAIL\n", - "7 7.27 10.11 87.1 429.1 PASS FAIL PASS PASS PASS FAIL\n", - "8 14.05 9.44 191.3 1059.4 PASS PASS PASS PASS PASS PASS\n", - "9 7.31 19.32 85.6 180.2 PASS PASS PASS PASS PASS PASS\n", - "10 31.40 17.78 2820.4 15930.3 PASS PASS PASS PASS FAIL FAIL\n", - "11 1.16 16.58 4754.6 21801.3 FAIL PASS FAIL FAIL PASS FAIL\n", - "12 20.39 16.81 847.0 5364.6 PASS PASS FAIL PASS FAIL FAIL\n", - "13 22.55 23.18 314.1 1562.1 PASS PASS FAIL PASS FAIL FAIL\n", - "14 42.84 8.88 521.7 4540.4 PASS PASS FAIL PASS PASS FAIL\n", - "15 38.41 12.81 1054.9 6414.1 PASS PASS FAIL PASS PASS FAIL\n", - "16 41.81 20.47 862.5 8377.2 PASS PASS FAIL PASS PASS FAIL\n", - "17 3.36 28.53 254.5 1417.1 PASS PASS PASS PASS PASS PASS\n", - "18 21.78 29.14 158.4 772.3 PASS PASS PASS PASS FAIL FAIL\n", - "19 29.73 30.26 121.4 450.1 PASS PASS PASS PASS FAIL FAIL\n", - "20 44.76 32.43 174.2 1291.9 PASS PASS PASS PASS PASS PASS\n", - "21 11.52 31.07 198.5 1104.6 PASS PASS FAIL PASS PASS FAIL\n", - "22 15.65 34.36 773.9 3558.8 PASS PASS FAIL PASS PASS FAIL\n", - "23 9.52 37.50 96.2 335.3 PASS PASS PASS PASS PASS PASS\n", - "24 7.62 41.29 83.1 322.5 PASS PASS FAIL PASS PASS FAIL\n", - "25 21.83 38.10 481.7 2246.5 PASS PASS FAIL PASS FAIL FAIL\n", - "26 25.95 40.06 371.2 1712.2 PASS PASS FAIL PASS FAIL FAIL\n", - "27 43.75 42.43 103.3 354.4 PASS PASS PASS PASS PASS PASS\n", - "28 16.45 45.49 718.1 4495.6 PASS PASS PASS PASS PASS PASS\n", - "29 34.03 47.05 116.5 309.2 FAIL PASS PASS PASS PASS FAIL\n", - "\n", - "7/30 sources pass all conditions\n", - "\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "background correlation correction\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess = tr.tessreduce(tpf='../../SN_individual/grb_test.fits',calibrate=False,quality_bitmask='hard',\n", - " shift_method='sep_core',diagnostic_plot=True)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5e99da5e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(-2.664845654130591, -2.7802437000662934, 3.6865743111980445)" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(tess.lc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "d92efabc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(-2.4662890730999476, -2.5770524187934285, 3.6609008801899585)" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(tess.lc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "7bbd23bd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(-5.855827893724092, -6.2644469983000555, 4.088039683834597)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(l[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "ad7d970f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(-2.3076208913462417, -2.4101956272303937, 3.582112650803093)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(tess2.lc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "cb4ecd9d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "6.732521131901457" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.nanstd(tess.lc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "77161bf2", - "metadata": {}, - "outputs": [], - "source": [ - "a = l[1] + 7" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "997bc95f", - "metadata": {}, - "outputs": [], - "source": [ - "b = a * 10**((20.44-16.4)/-2.5)" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "7aba796b", - "metadata": {}, - "outputs": [], - "source": [ - "c = -2.5*np.log10(a) + 20.44" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "b4be3c02", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(b/1000)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "994d2a90", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Optimal PSF shift: [-0.8 -0.48753171]\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "l,b = tess.diff_lc(phot_method='psf',plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "91fc4ebb", - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", - "made source mask\n", - "calculating background\n", - "background subtracted\n", - "aligning images\n", - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n", - "background correlation correction\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess2 = tr.tessreduce(tpf='../../SN_individual/grb_test.fits',calibrate=False,quality_bitmask='hard')" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "f15d2632", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess2.lc[1])\n", - "plt.plot(tess.lc[1],'.',alpha=0.5)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "fcaaa5a3", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.shift[:,0],'C1')\n", - "plt.plot(tess.shift[:,1])\n", - "plt.plot(tess2.shift[:,0],'C1--')\n", - "plt.plot(tess2.shift[:,1],'C0--')" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "e87280b0", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.\n", - "made source mask\n", - "calculating background\n", - "background subtracted\n", - "aligning images\n", - "Something went wrong, switching to serial\n", - "!!Re-running for difference image!!\n", - "Traceback (most recent call last):\n", - " File \"/Users/rri38/miniconda3/lib/python3.12/site-packages/tessreduce/tessreduce.py\", line 2247, in reduce\n", - " self.shift_images()\n", - " File \"/Users/rri38/miniconda3/lib/python3.12/site-packages/tessreduce/tessreduce.py\", line 1140, in shift_images\n", - " shifted[i] = shift(shifted[i],[self.shift[i,0],self.shift[i,1]],mode='nearest',order=5)#mode='constant',cval=np.nan)\n", - " ~~~~~~~~~~^^^^^\n", - "TypeError: 'NoneType' object is not subscriptable\n", - "\n" - ] - } - ], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "4a103495", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/Users/rri38/Documents/work/code/tess/tessreduce/development\r\n" - ] - } - ], - "source": [ - "! pwd" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "8cca1616", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.bkg[:,20,20])" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "26d5aed4", - "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_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.qe[10])" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "65c99ca4", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[10],vmax=10,vmin=-10)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "4a63ee0b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(-2.834884747460821, -3.0314780363350167, 4.34404825446251)" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(tess.lc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "1f7e0634", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Optimal PSF shift: [-0.79997333 -0.8 ]\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "l = tess.diff_lc(phot_method='psf',plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "d9c9a8e7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(-2.342124821349616, -2.404446153370343, 3.2283203092228967)" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(l[0][1])" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "bc065d0b", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.lc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "06897336", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(-2.342124821349616, -2.404446153370343, 3.2283203092228967)" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tr.sigma_clipped_stats(l[0][1])" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "b6fd4a57", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "!!! WARNING no MJD time specified, using default of 59000\n", - "| Sector | Camera | CCD | Covers | Time difference |\n", - "| | | | | (days) |\n", - "|----------+----------+-------+----------+--------------------|\n", - "| 7 | 1 | 4 | False | -484.406 |\n", - "| 34 | 1 | 4 | False | 228.25 |\n", - "| 44 | 4 | 2 | False | 499.688 |\n", - "| 45 | 2 | 1 | False | 525.007 |\n", - "| 46 | 1 | 4 | False | 551.066 |\n", - "| 71 | 4 | 3 | False | 1233.53 |\n", - "| 72 | 2 | 4 | False | 1259.68 |\n" - ] - } - ], - "source": [ - "obs = tr.spacetime_lookup(ra = 117.08058333333332,dec = 11.40943888888889)" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "2afa459a", - "metadata": {}, - "outputs": [], - "source": [ - "from astropy.stats import sigma_clipped_stats" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "2134197f", - "metadata": {}, - "outputs": [], - "source": [ - "grad = np.gradient(tess.bkg[:,25,25],lc[0])" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "ac0d2e88", - "metadata": {}, - "outputs": [], - "source": [ - "m,med,std = sigma_clipped_stats(tess.bkg[:,25,25])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "344593e5", - "metadata": {}, - "outputs": [], - "source": [ - "from scipy.signal import sav" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "5e23c338", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.bkg[:,25,25],'.')\n", - "plt.axhline(med + 5*std)" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "id": "c8818354", - "metadata": {}, - "outputs": [], - "source": [ - "from scipy.signal import savgol_filter" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "78beb9e5", - "metadata": {}, - "outputs": [], - "source": [ - "sav = savgol_filter(tess.bkg[ind,25,25][:1620],201,4)\n", - "sav = savgol_filter(tess.bkg[ind,25,25][1630:],201,4)" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "id": "8d72b642", - "metadata": {}, - "outputs": [], - "source": [ - "from copy import deepcopy" - ] - }, - { - "cell_type": "code", - "execution_count": 82, - "id": "912fd3fd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1.388888888888889" - ] - }, - "execution_count": 82, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "200*10/60/24" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "id": "964e9911", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([ 0, 1745])" - ] - }, - "execution_count": 84, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 87, - "id": "3ce16e6a", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 88, - "id": "b90c9642", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([ 0, 1627, 3258])" - ] - }, - "execution_count": 88, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "breaks" - ] - }, - { - "cell_type": "code", - "execution_count": 95, - "id": "b2c81239", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([ 64, 67, 68, ..., 3468, 3469, 3470])" - ] - }, - "execution_count": 95, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ind" - ] - }, - { - "cell_type": "code", - "execution_count": 94, - "id": "b241faab", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 94, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ind = np.where(abs(grad) < (med +3*std))[0]\n", - "\n", - "time = tess.tpf.time.mjd\n", - "\n", - "breaks = np.where(np.diff(time[ind])> 1)[0]\n", - "breaks = np.insert(breaks,0,0)\n", - "breaks = np.append(breaks,len(time[ind]))\n", - "\n", - "new_bkg = deepcopy(tess.bkg[:,25,25])\n", - "\n", - "for i in range(len(breaks) - 1):\n", - " sav = savgol_filter(new_bkg[ind][breaks[i]:breaks[i+1]],201,4)\n", - " plt.figure()\n", - " plt.plot(new_bkg[ind][breaks[i]:breaks[i+1]],'.')\n", - " plt.plot(sav)\n", - " new_bkg[ind][breaks[i]:breaks[i+1]] = sav\n", - " \n", - "#new_bkg[]\n", - "\n", - "#gaussian_filter1d(sigma_idx, sigma=max(1, 1.0 / dt_hrs))\n", - "\n", - "plt.figure()\n", - "plt.plot(tess.bkg[:,25,25],'.')\n", - "plt.plot(new_bkg)\n", - "#plt.axhline(med + 5*std)" - ] - }, - { - "cell_type": "code", - "execution_count": 96, - "id": "faa6b4db", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 96, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ind = abs(grad) < (med + 3*std)\n", - "\n", - "time = tess.tpf.time.mjd\n", - "\n", - "ind_where = np.where(ind)[0] # integer indices into new_bkg\n", - "\n", - "breaks = np.where(np.diff(time[ind]) > 1)[0]\n", - "breaks = np.insert(breaks, 0, 0)\n", - "breaks = np.append(breaks, len(time[ind]))\n", - "\n", - "new_bkg = deepcopy(tess.bkg[:,25,25])\n", - "\n", - "for i in range(len(breaks) - 1):\n", - " seg_idx = ind_where[breaks[i]:breaks[i+1]]\n", - " sav = savgol_filter(new_bkg[seg_idx], 201, 4)\n", - " plt.figure()\n", - " plt.plot(new_bkg[seg_idx], '.')\n", - " plt.plot(sav)\n", - " new_bkg[seg_idx] = sav # writes back correctly via integer indexing\n", - " \n", - "plt.figure()\n", - "plt.plot(tess.bkg[:,25,25],'.')\n", - "plt.plot(new_bkg)\n", - "#plt.axhline(med + 5*std)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2f642bfb", - "metadata": {}, - "outputs": [], - "source": [ - "def bkg_temporal_smooth(self,window_size=None):\n", - " if window_size is None:\n", - " window_size = self._bkg_temporal_window # still need to decide what this is \n", - " \n", - " grad = np.gradient(self.bkg[:,25,25],lc[0])\n", - " time = self.mjd\n", - " m,med,std = sigma_clipped_stats(abs(grad))\n", - " ind = abs(grad) < (med + 5*std)\n", - " ind_where = np.where(ind)[0]\n", - "\n", - " breaks = np.where(np.diff(time[ind]) > 1)[0]+1\n", - " breaks = np.insert(breaks, 0, 0)\n", - " breaks = np.append(breaks, len(time[ind]))\n", - "\n", - " new_bkg = self.bkg.copy() # shape (T, X, Y)\n", - "\n", - " for i in range(len(breaks) - 1):\n", - " seg_idx = ind_where[breaks[i]:breaks[i+1]]\n", - " seg = new_bkg[seg_idx] # (n_seg, X, Y)\n", - " sav = savgol_filter(seg, 501, 1, axis=0) # (n_seg, X, Y)\n", - "\n", - " # per-pixel residual threshold\n", - " resid = np.abs(seg - sav) # (n_seg, X, Y)\n", - " threshold = np.median(resid, axis=0) + 5 * np.std(resid, axis=0) # (X, Y)\n", - "\n", - " exceeds = resid > threshold[np.newaxis] # (n_seg, X, Y)\n", - "\n", - " # leading bad run: cumprod stays 1 only while all preceding values were True\n", - " start_clip = np.cumprod(exceeds,axis=0).sum(axis=0) # (X, Y)\n", - " end_clip = len(seg_idx) - np.cumprod(exceeds[::-1], axis=0).sum(axis=0)\n", - "\n", - " # use sav only within [start_clip, end_clip), raw outside\n", - " t = np.arange(len(seg_idx))[:, np.newaxis, np.newaxis] # (n_seg, 1, 1)\n", - " use_sav = (t >= start_clip) & (t < end_clip)\n", - "\n", - " new_bkg[seg_idx] = np.where(use_sav, sav, seg)\n", - "\n", - "# flux = deepcopy(self.flux)\n", - "# flux += self.bkg - new_bkg\n", - " med = sigma_clipped_stats(flux,axis=(1,2))[1]\n", - " flux = flux - med[:,np.newaxis,np.newaxis]\n", - " new_bkg += med[:,np.newaxis,np.newaxis]\n", - " self.bkg = new_bkg\n", - " self.flux = flux\n" - ] - }, - { - "cell_type": "code", - "execution_count": 214, - "id": "288e9688", - "metadata": {}, - "outputs": [], - "source": [ - "ind = abs(grad) < (med + 5*std)\n", - "ind_where = np.where(ind)[0]\n", - "\n", - "breaks = np.where(np.diff(time[ind]) > 1)[0]+1\n", - "breaks = np.insert(breaks, 0, 0)\n", - "breaks = np.append(breaks, len(time[ind]))\n", - "\n", - "new_bkg = tess.bkg.copy() # shape (T, X, Y)\n", - "\n", - "for i in range(len(breaks) - 1):\n", - " seg_idx = ind_where[breaks[i]:breaks[i+1]]\n", - " seg = new_bkg[seg_idx] # (n_seg, X, Y)\n", - " sav = savgol_filter(seg, 501, 1, axis=0) # (n_seg, X, Y)\n", - "\n", - " # per-pixel residual threshold\n", - " resid = np.abs(seg - sav) # (n_seg, X, Y)\n", - " threshold = np.median(resid, axis=0) + 5 * np.std(resid, axis=0) # (X, Y)\n", - "\n", - " exceeds = resid > threshold[np.newaxis] # (n_seg, X, Y)\n", - "\n", - " # leading bad run: cumprod stays 1 only while all preceding values were True\n", - " start_clip = np.cumprod(exceeds, axis=0).sum(axis=0) # (X, Y)\n", - " end_clip = len(seg_idx) - np.cumprod(exceeds[::-1], axis=0).sum(axis=0)\n", - "\n", - " # use sav only within [start_clip, end_clip), raw outside\n", - " t = np.arange(len(seg_idx))[:, np.newaxis, np.newaxis] # (n_seg, 1, 1)\n", - " use_sav = (t >= start_clip) & (t < end_clip)\n", - "\n", - " new_bkg[seg_idx] = np.where(use_sav, sav, seg)\n", - "\n", - "flux = deepcopy(tess.flux)\n", - "flux += tess.bkg - new_bkg\n", - "med = sigma_clipped_stats(flux,axis=(1,2))[1]\n", - "flux = flux - med[:,np.newaxis,np.newaxis]\n", - "new_bkg += med[:,np.newaxis,np.newaxis]\n" - ] - }, - { - "cell_type": "code", - "execution_count": 218, - "id": "e682f77c", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 218, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(np.nansum(tess.flux[:,24:27,24:27],axis=(1,2)),label='old')\n", - "plt.plot(np.nansum(flux[:,24:27,24:27],axis=(1,2)),label='new')\n", - "#plt.plot(np.nansum(aflux[:,24:27,24:27],axis=(1,2)),label='new')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 190, - "id": "20f040b2", - "metadata": {}, - "outputs": [], - "source": [ - "np.save('flux_test.npy',tess.flux)" - ] - }, - { - "cell_type": "code", - "execution_count": 219, - "id": "28225171", - "metadata": {}, - "outputs": [], - "source": [ - "lc1 = np.nansum(tess.flux[:,24:27,24:27],axis=(1,2))\n", - "lc2 = np.nansum(flux[:,24:27,24:27],axis=(1,2))" - ] - }, - { - "cell_type": "code", - "execution_count": 224, - "id": "81bd2fcb", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "27.354153455917178" - ] - }, - "execution_count": 224, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sigma_clipped_stats(lc1)[2] * 3" - ] - }, - { - "cell_type": "code", - "execution_count": 225, - "id": "1cd832e0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "15.741954697000537" - ] - }, - "execution_count": 225, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sigma_clipped_stats(lc2)[2] *3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "49daa793", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 222, - "id": "38ed0418", - "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_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 222, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "j = 1835#2855\n", - "plt.figure()\n", - "plt.subplot(121)\n", - "plt.imshow(tess.flux[j],vmin=-10,vmax=10)\n", - "\n", - "plt.subplot(122)\n", - "plt.imshow(flux[j],vmin=-10,vmax=10)" - ] - }, - { - "cell_type": "code", - "execution_count": 151, - "id": "9c8f508d", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 159, - "id": "80fe9863", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([ 0.13595049, 0.21746506, 0.10541646, ..., -0.1851571 ,\n", - " 0.30301034, 0.19434366])" - ] - }, - "execution_count": 159, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[1]" - ] - }, - { - "cell_type": "code", - "execution_count": 147, - "id": "2a8ff1e5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.28194623356385085, 0.2497329419029134, 1.2707684836536026)" - ] - }, - "execution_count": 147, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sigma_clipped_stats(tess.flux[j] + tess.bkg[j] - new_bkg[j])" - ] - }, - { - "cell_type": "code", - "execution_count": 163, - "id": "5c5595c0", - "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_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "ind = abs(grad) < (med + 5*std)\n", - "ind_where = np.where(ind)[0]\n", - "\n", - "breaks = np.where(np.diff(time[ind]) > 1)[0]+1\n", - "breaks = np.insert(breaks, 0, 0)\n", - "breaks = np.append(breaks, len(time[ind]))\n", - "\n", - "new_bkg = deepcopy(tess.bkg[:,25,25])\n", - "\n", - "for i in range(len(breaks) - 1):\n", - " seg_idx = ind_where[breaks[i]:breaks[i+1]]\n", - " seg = new_bkg[seg_idx]\n", - " sav = savgol_filter(seg, 51, 3)\n", - "\n", - " # find poorly-fit edge points and revert to original\n", - " resid = np.abs(seg - sav)\n", - " threshold = np.median(resid) + 5 * np.std(resid)\n", - "\n", - " # clip start: walk inward until residual is acceptable\n", - " start_clip = 0\n", - " for j in range(len(sav)):\n", - " if resid[j] > threshold:\n", - " start_clip = j + 1\n", - " else:\n", - " break\n", - "\n", - " # clip end: walk inward from the right\n", - " end_clip = len(sav)\n", - " for j in range(len(sav) - 1, -1, -1):\n", - " if resid[j] > threshold:\n", - " end_clip = j\n", - " else:\n", - " break\n", - "\n", - " sav[:start_clip] = seg[:start_clip]\n", - " sav[end_clip:] = seg[end_clip:]\n", - "\n", - "# plt.figure()\n", - "# plt.plot(seg, '.')\n", - "# plt.plot(sav)\n", - " new_bkg[seg_idx] = sav\n", - " \n", - "flux = deepcopy(tess.flux)\n", - "flux += tess.bkg - new_bkg\n", - "med = sigma_clipped_stats(flux,axis=(1,2))[1]\n", - "flux = flux - med\n", - " \n", - " \n", - "# plt.figure()\n", - "# plt.plot(tess.bkg[ind,25,25],'.')\n", - "# plt.plot(new_bkg[ind])\n", - "\n", - "# plt.figure()\n", - "# plt.plot(tess.bkg[:,25,25]-new_bkg,'.')\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 161, - "id": "19c481da", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(3471,)" - ] - }, - "execution_count": 161, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "new_bkg.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 167, - "id": "7639d232", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "ename": "ValueError", - "evalue": "x and y can be no greater than 2D, but have shapes (3471,) and (3471, 50, 50)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[167], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m plt\u001b[38;5;241m.\u001b[39mfigure()\n\u001b[0;32m----> 2\u001b[0m \u001b[43mplt\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mplot\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnew_bkg\u001b[49m\u001b[43m,\u001b[49m\u001b[43mlabel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mbkg\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 3\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(tess\u001b[38;5;241m.\u001b[39mflux[:,\u001b[38;5;241m25\u001b[39m,\u001b[38;5;241m25\u001b[39m],\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m'\u001b[39m,label\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlc\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 4\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(tess\u001b[38;5;241m.\u001b[39mflux[:,\u001b[38;5;241m25\u001b[39m,\u001b[38;5;241m25\u001b[39m] \u001b[38;5;241m+\u001b[39m tess\u001b[38;5;241m.\u001b[39mbkg[:,\u001b[38;5;241m25\u001b[39m,\u001b[38;5;241m25\u001b[39m] \u001b[38;5;241m-\u001b[39m new_bkg,\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m'\u001b[39m,label\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlc\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/matplotlib/pyplot.py:3838\u001b[0m, in \u001b[0;36mplot\u001b[0;34m(scalex, scaley, data, *args, **kwargs)\u001b[0m\n\u001b[1;32m 3830\u001b[0m \u001b[38;5;129m@_copy_docstring_and_deprecators\u001b[39m(Axes\u001b[38;5;241m.\u001b[39mplot)\n\u001b[1;32m 3831\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mplot\u001b[39m(\n\u001b[1;32m 3832\u001b[0m \u001b[38;5;241m*\u001b[39margs: \u001b[38;5;28mfloat\u001b[39m \u001b[38;5;241m|\u001b[39m ArrayLike \u001b[38;5;241m|\u001b[39m \u001b[38;5;28mstr\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 3836\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[1;32m 3837\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28mlist\u001b[39m[Line2D]:\n\u001b[0;32m-> 3838\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mgca\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mplot\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 3839\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3840\u001b[0m \u001b[43m \u001b[49m\u001b[43mscalex\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mscalex\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3841\u001b[0m \u001b[43m \u001b[49m\u001b[43mscaley\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mscaley\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3842\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m{\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdata\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m}\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mis\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3843\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3844\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/matplotlib/axes/_axes.py:1777\u001b[0m, in \u001b[0;36mAxes.plot\u001b[0;34m(self, scalex, scaley, data, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1534\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 1535\u001b[0m \u001b[38;5;124;03mPlot y versus x as lines and/or markers.\u001b[39;00m\n\u001b[1;32m 1536\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1774\u001b[0m \u001b[38;5;124;03m(``'green'``) or hex strings (``'#008000'``).\u001b[39;00m\n\u001b[1;32m 1775\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 1776\u001b[0m kwargs \u001b[38;5;241m=\u001b[39m cbook\u001b[38;5;241m.\u001b[39mnormalize_kwargs(kwargs, mlines\u001b[38;5;241m.\u001b[39mLine2D)\n\u001b[0;32m-> 1777\u001b[0m lines \u001b[38;5;241m=\u001b[39m [\u001b[38;5;241m*\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_lines(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m*\u001b[39margs, data\u001b[38;5;241m=\u001b[39mdata, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)]\n\u001b[1;32m 1778\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m line \u001b[38;5;129;01min\u001b[39;00m lines:\n\u001b[1;32m 1779\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39madd_line(line)\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/matplotlib/axes/_base.py:297\u001b[0m, in \u001b[0;36m_process_plot_var_args.__call__\u001b[0;34m(self, axes, data, return_kwargs, *args, **kwargs)\u001b[0m\n\u001b[1;32m 295\u001b[0m this \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m args[\u001b[38;5;241m0\u001b[39m],\n\u001b[1;32m 296\u001b[0m args \u001b[38;5;241m=\u001b[39m args[\u001b[38;5;241m1\u001b[39m:]\n\u001b[0;32m--> 297\u001b[0m \u001b[38;5;28;01myield from\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_plot_args\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 298\u001b[0m \u001b[43m \u001b[49m\u001b[43maxes\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mthis\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mambiguous_fmt_datakey\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mambiguous_fmt_datakey\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 299\u001b[0m \u001b[43m \u001b[49m\u001b[43mreturn_kwargs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mreturn_kwargs\u001b[49m\n\u001b[1;32m 300\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/matplotlib/axes/_base.py:497\u001b[0m, in \u001b[0;36m_process_plot_var_args._plot_args\u001b[0;34m(self, axes, tup, kwargs, return_kwargs, ambiguous_fmt_datakey)\u001b[0m\n\u001b[1;32m 494\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mx and y must have same first dimension, but \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 495\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhave shapes \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mx\u001b[38;5;241m.\u001b[39mshape\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m and \u001b[39m\u001b[38;5;132;01m{\u001b[39;00my\u001b[38;5;241m.\u001b[39mshape\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 496\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m x\u001b[38;5;241m.\u001b[39mndim \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m2\u001b[39m \u001b[38;5;129;01mor\u001b[39;00m y\u001b[38;5;241m.\u001b[39mndim \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m2\u001b[39m:\n\u001b[0;32m--> 497\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mx and y can be no greater than 2D, but have \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 498\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mshapes \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mx\u001b[38;5;241m.\u001b[39mshape\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m and \u001b[39m\u001b[38;5;132;01m{\u001b[39;00my\u001b[38;5;241m.\u001b[39mshape\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 499\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m x\u001b[38;5;241m.\u001b[39mndim \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m 500\u001b[0m x \u001b[38;5;241m=\u001b[39m x[:, np\u001b[38;5;241m.\u001b[39mnewaxis]\n", - "\u001b[0;31mValueError\u001b[0m: x and y can be no greater than 2D, but have shapes (3471,) and (3471, 50, 50)" - ] - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(new_bkg,label='bkg')\n", - "plt.plot(tess.flux[:,25,25],'.',label='lc')\n", - "plt.plot(tess.flux[:,25,25] + tess.bkg[:,25,25] - new_bkg,'.',label='lc')\n", - "plt.legend()\n", - "plt.ylim(-4,20)" - ] - }, - { - "cell_type": "code", - "execution_count": 126, - "id": "649004bf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.1992238794252621, 0.14485954705463833, 1.2108414313258078)" - ] - }, - "execution_count": 126, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sigma_clipped_stats(tess.flux[:,25,25])" - ] - }, - { - "cell_type": "code", - "execution_count": 125, - "id": "9f2fd400", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.18983479459023306, 0.13764954448826572, 0.9358091876427621)" - ] - }, - "execution_count": 125, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sigma_clipped_stats(tess.flux[:,25,25] + tess.bkg[:,25,25] - new_bkg)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2075a649", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy.ndimage import gaussian_filter1d\n", - "\n", - "def adaptive_gaussian_smooth(time, bkg, sigma_min_hrs=0.5, sigma_max_hrs=6,\n", - " n_levels=15, gap_threshold_hrs=1.0,\n", - " raw_grad_threshold=0.3, spike_nsigma=5):\n", - " '''\n", - " Adaptive Gaussian smoothing in physical time units, respecting data gaps.\n", - "\n", - " Points are left as raw data if they have a high local gradient OR are\n", - " significantly elevated above the local baseline (catches full spike decay).\n", - "\n", - " Parameters\n", - " ----------\n", - " time : 1D array of times (days)\n", - " bkg : 1D array of background values\n", - " sigma_min_hrs : minimum smoothing width in hours (near rapid changes)\n", - " sigma_max_hrs : maximum smoothing width in hours (steady regions)\n", - " n_levels : number of pre-computed sigma levels\n", - " gap_threshold_hrs : gaps larger than this split data into independent segments\n", - " raw_grad_threshold : gradient fraction [0-1] above which points are left raw\n", - " spike_nsigma : points more than this many sigma above local baseline\n", - " are also left raw\n", - " '''\n", - " dt_hrs = np.median(np.diff(time)) * 24\n", - " sigma_min = sigma_min_hrs / dt_hrs\n", - " sigma_max = sigma_max_hrs / dt_hrs\n", - "\n", - " gaps = np.diff(time) * 24\n", - " seg_breaks = np.where(gaps > gap_threshold_hrs)[0] + 1\n", - " seg_starts = np.concatenate([[0], seg_breaks])\n", - " seg_ends = np.concatenate([seg_breaks, [len(bkg)]])\n", - "\n", - " result = bkg.copy()\n", - "\n", - " for s, e in zip(seg_starts, seg_ends):\n", - " seg = bkg[s:e]\n", - " sigmas = np.geomspace(sigma_min, sigma_max, n_levels)\n", - "\n", - " # Robust baseline and noise estimate from the lower 60th percentile\n", - " lo = seg <= np.percentile(seg, 60)\n", - " baseline = np.median(seg[lo])\n", - " noise = np.median(np.abs(seg[lo] - baseline))\n", - " noise = max(noise, 1e-6)\n", - "\n", - " # Gradient-based raw mask\n", - " grad = np.abs(np.gradient(seg))\n", - " p_hi = np.percentile(grad, 99)\n", - " grad_norm = np.clip(grad / (p_hi + 1e-10), 0, 1)\n", - "\n", - " # Combined raw mask: high gradient OR elevated above baseline\n", - " raw_mask = (grad_norm >= raw_grad_threshold) | (seg > baseline + spike_nsigma * noise)\n", - " smooth_mask = ~raw_mask\n", - "\n", - " # Sigma index: high gradient -> sigma_min, flat -> sigma_max\n", - " sigma_idx = (1.0 - grad_norm ** 2) * (n_levels - 1)\n", - " sigma_idx = gaussian_filter1d(sigma_idx, sigma=max(1, 1.0 / dt_hrs))\n", - " sigma_idx = np.clip(sigma_idx, 0, n_levels - 1)\n", - "\n", - " # Pre-compute smoothed versions at each sigma level\n", - " smoothed = np.array([gaussian_filter1d(seg, sigma=sig, mode='nearest')\n", - " for sig in sigmas])\n", - "\n", - " # Interpolate between adjacent levels\n", - " idx_lo = np.clip(sigma_idx.astype(int), 0, n_levels - 2)\n", - " idx_hi = idx_lo + 1\n", - " frac = sigma_idx - idx_lo\n", - " val_lo = np.take_along_axis(smoothed, idx_lo[np.newaxis], axis=0)[0]\n", - " val_hi = np.take_along_axis(smoothed, idx_hi[np.newaxis], axis=0)[0]\n", - " blended = (1.0 - frac) * val_lo + frac * val_hi\n", - "\n", - " seg_result = seg.copy()\n", - " seg_result[smooth_mask] = blended[smooth_mask]\n", - " result[s:e] = seg_result\n", - "\n", - " return result" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "edda750e", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5e6b61e0", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3bb5c191", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "b77a282e", - "metadata": {}, - "outputs": [], - "source": [ - "lc = np.array([tess.tpf.time.mjd,tess.bkg[:,25,25]])" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "ad887fc6", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(2, 3471)" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "lc.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "c3b6c13d", - "metadata": {}, - "outputs": [], - "source": [ - "np.save('test_bkg.npy',lc)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "95ba889c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/Users/rri38/Documents/work/code/tess/tessreduce/development\r\n" - ] - } - ], - "source": [ - "!pwd" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "a189dc08", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.bkg[1000])" - ] - }, - { - "cell_type": "code", - "execution_count": 425, - "id": "7f90dca7", - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"\n", - "TESSSourceFinder\n", - "================\n", - "Multi-scale Mexican-hat SEP source detection for TESS reference images.\n", - "\n", - "Best-fit parameters derived from Gaia recall optimisation on sector 38,\n", - "cam 4, ccd 1 (20.5 arcsec/px, 256x256 cut):\n", - "\n", - " 83% Gaia recall (G < 18.5), median position error 0.95 px\n", - " 100% recall for G < 14, sub-0.2 px position accuracy\n", - "\"\"\"\n", - "\n", - "import numpy as np\n", - "import pandas as pd\n", - "import sep\n", - "import warnings\n", - "warnings.filterwarnings(\"ignore\")\n", - "\n", - "\n", - "class TESSSourceFinder:\n", - " \"\"\"\n", - " Detect point sources in a TESS reference image using multi-scale\n", - " Mexican-hat convolution kernels and SEP (Source Extractor Python).\n", - "\n", - " Parameters\n", - " ----------\n", - " thresh : float\n", - " Detection threshold in units of background RMS. Default 0.30.\n", - " bw : int\n", - " Background mesh cell size in pixels. Default 24.\n", - " fwhm_min, fwhm_max : float\n", - " Range of kernel FWHM values (pixels) to sweep. Default 0.7–2.0.\n", - " n_scales : int\n", - " Number of kernel scales between fwhm_min and fwhm_max. Default 10.\n", - " deblend_nthresh : int\n", - " SEP deblending threshold levels. Default 128.\n", - " deblend_cont : float\n", - " SEP minimum contrast ratio for deblending. Default 5e-5.\n", - " dedup_radius : float\n", - " Pixels — detections from different scales within this distance are\n", - " deduplicated, keeping the one with the highest flux. Default 1.0.\n", - " ref : ndarray (H, W), optional\n", - " Reference image (tessreduce .ref). When provided, a per-pixel\n", - " noise map is built as noise[y,x] = sqrt(bkg_rms² + (k*ref[y,x])²)\n", - " and used as the SEP error map.\n", - " residual_k : float, optional\n", - " Fractional systematic residual coefficient. Typical TESS value\n", - " ~0.0078. If None, estimated automatically from the ref image.\n", - " \"\"\"\n", - "\n", - " def __init__(\n", - " self,\n", - " thresh: float = 0.30,\n", - " bw: int = 24,\n", - " fwhm_min: float = 0.7,\n", - " fwhm_max: float = 2.0,\n", - " n_scales: int = 10,\n", - " deblend_nthresh: int = 128,\n", - " deblend_cont: float = 5e-5,\n", - " dedup_radius: float = 1.0,\n", - " ref: np.ndarray = None,\n", - " residual_k: float = None,\n", - " ):\n", - " self.thresh = thresh\n", - " self.bw = bw\n", - " self.fwhm_min = fwhm_min\n", - " self.fwhm_max = fwhm_max\n", - " self.n_scales = n_scales\n", - " self.deblend_nthresh = deblend_nthresh\n", - " self.deblend_cont = deblend_cont\n", - " self.dedup_radius = dedup_radius\n", - " self.ref = np.asarray(ref, dtype=np.float64) if ref is not None else None\n", - " self.residual_k = residual_k\n", - "\n", - " self._fwhms = np.linspace(fwhm_min, fwhm_max, n_scales)\n", - " self._kernels = [self._mexhat(f) for f in self._fwhms]\n", - "\n", - " # ── public API ────────────────────────────────────────────────────────────\n", - "\n", - " def find(self, image: np.ndarray) -> pd.DataFrame:\n", - " \"\"\"\n", - " Detect sources in a 2-D image or a 3-D timeseries.\n", - "\n", - " Parameters\n", - " ----------\n", - " image : ndarray (H, W) or (T, H, W)\n", - " For a single image, returns the standard detection DataFrame.\n", - " For a timeseries, detection is parallelised across frames with\n", - " joblib and a 'frame' column (0-indexed) is added.\n", - "\n", - " Returns\n", - " -------\n", - " sources : DataFrame\n", - " Columns: x, y, flux, peak, a, b, theta, flag, detection_fwhm,\n", - " snr, ellipticity, neg_extent [, snr_model if ref provided]\n", - " [, frame if timeseries input]\n", - " \"\"\"\n", - " image = np.asarray(image)\n", - " if image.ndim == 2:\n", - " return self._find_single(image)\n", - " elif image.ndim == 3:\n", - " return self._find_cube(image)\n", - " else:\n", - " raise ValueError(f\"image must be 2D or 3D, got shape {image.shape}\")\n", - "\n", - " def filter(self, sources: pd.DataFrame,\n", - " snr_min: float = 2.0,\n", - " snr_model_min: float = 2.0,\n", - " ellipticity_max: float = 0.6,\n", - " neg_extent_max: float = 6,\n", - " peak_min: float = None,\n", - " flux_min: float = None) -> pd.DataFrame:\n", - " \"\"\"\n", - " Apply quality filters to remove contamination from differenced-image\n", - " detections while preserving real astrophysical sources.\n", - "\n", - " Contamination taxonomy (from analysis of TESS sector 38 diff cube):\n", - " ┌──────────────────────────────────┬──────────────────────────────────────┐\n", - " │ Type │ Signature │\n", - " ├──────────────────────────────────┼──────────────────────────────────────┤\n", - " │ Ringing artefact (60%) │ snr < 0, neg_extent > 5 │\n", - " │ Mexican-hat fires on positive │ Aperture captures surrounding │\n", - " │ peak of a bright star's halo │ negative bowl from PSF halo │\n", - " ├──────────────────────────────────┼──────────────────────────────────────┤\n", - " │ Faint halo artefact (24%) │ snr < 0, neg_extent 2–5 │\n", - " │ Weaker version of above │ │\n", - " ├──────────────────────────────────┼──────────────────────────────────────┤\n", - " │ Cosmic ray / scattered light │ snr_model >> 10 on dim sky, │\n", - " │ cluster artefact │ snr < 0, multiple nearby detections │\n", - " └──────────────────────────────────┴──────────────────────────────────────┘\n", - "\n", - " Parameters\n", - " ----------\n", - " sources : DataFrame\n", - " Output of find(). If ref was not provided, snr_model will be\n", - " absent and that criterion is skipped.\n", - " snr_min : float\n", - " Minimum aperture SNR. Default 2.0.\n", - " snr_model_min : float\n", - " Minimum peak / ref-scaled noise. Skipped if snr_model column is\n", - " absent (i.e. no ref image was provided). Default 2.0.\n", - " ellipticity_max : float\n", - " Maximum ellipticity (1 − b/a). Default 0.6.\n", - " neg_extent_max : float or None\n", - " Maximum neg_extent (sigma-normalised negative bowl depth).\n", - " None = no cut.\n", - " peak_min : float or None\n", - " Minimum peak pixel value above background. None = no cut.\n", - " flux_min : float or None\n", - " Minimum isophotal flux above background. None = no cut.\n", - "\n", - " Returns\n", - " -------\n", - " filtered : DataFrame, reset index.\n", - " \"\"\"\n", - " mask = pd.Series(True, index=sources.index)\n", - "\n", - " mask &= sources[\"snr\"] >= snr_min\n", - " mask &= sources[\"ellipticity\"].fillna(1.0) < ellipticity_max\n", - "\n", - " if \"snr_model\" in sources.columns:\n", - " mask &= sources[\"snr_model\"] >= snr_model_min\n", - "\n", - " if neg_extent_max is not None and \"neg_extent\" in sources.columns:\n", - " mask &= sources[\"neg_extent\"].fillna(0.0) <= neg_extent_max\n", - "\n", - " if peak_min is not None:\n", - " mask &= sources[\"peak\"] >= peak_min\n", - "\n", - " if flux_min is not None:\n", - " mask &= sources[\"flux\"] >= flux_min\n", - "\n", - " mask &= (sources['flag'] == 0) | (sources['flag'] == 1)\n", - " \n", - " return sources[mask].reset_index(drop=True)\n", - "\n", - " def group(self, detections: pd.DataFrame,\n", - " spatial_eps: float = 1.5,\n", - " max_speed: float = 0.3,\n", - " event_gap: int = 10) -> pd.DataFrame:\n", - " \"\"\"\n", - " Cluster detections into stationary sources using DBSCAN on (x, y),\n", - " then purge moving objects that were absorbed into spatial clusters.\n", - "\n", - " Problem with pure spatial clustering: an asteroid crossing near a star\n", - " will have its detections folded into that star's cluster (they share the\n", - " same sky region for a few frames), so the asteroid never appears as an\n", - " unassigned detection and is invisible to find_asteroids().\n", - "\n", - " Fix — two-pass consistency check:\n", - " Pass 1: spatial DBSCAN groups detections that are co-located in (x,y)\n", - " regardless of time. This correctly groups stationary stars.\n", - " Pass 2: for every multi-frame cluster, compute the per-frame SNR-\n", - " weighted centroid and fit a linear velocity. If the inferred\n", - " speed exceeds max_speed px/frame the cluster contains a moving\n", - " object. Detections whose residual from the star's SNR-weighted\n", - " mean position exceeds spatial_eps are re-labelled as unassigned\n", - " (source_id = -1) so find_asteroids() can pick them up.\n", - "\n", - " Parameters\n", - " ----------\n", - " detections : DataFrame\n", - " Output of find() on a 3-D timeseries.\n", - " spatial_eps : float\n", - " DBSCAN neighbourhood radius in pixels. Default 1.5.\n", - " min_frames : int\n", - " Minimum number of distinct frames a cluster must span to be\n", - " labelled as a stationary source. Default 2.\n", - " max_speed : float\n", - " Maximum allowed drift of a cluster's per-frame centroid in\n", - " px/frame. Clusters with fitted velocity exceeding this have their\n", - " off-position detections split out as unassigned. Default 0.3.\n", - " event_gap : int\n", - " Frame gap that separates distinct events for the same stationary\n", - " source. Within a source group, any pair of consecutive detections\n", - " separated by more than event_gap frames starts a new event.\n", - " Default 10 frames.\n", - "\n", - " Returns\n", - " -------\n", - " detections : DataFrame with added columns:\n", - " source_id — int cluster label (>= 0 stationary, -1 unassigned)\n", - " event_id — per-source event index (0, 1, 2, …) ordered in time;\n", - " NaN for unassigned detections (source_id == -1)\n", - " x_w, y_w — SNR-weighted centroid of the stationary source this\n", - " detection belongs to; copies raw x, y for unassigned.\n", - " \"\"\"\n", - " if \"frame\" not in detections.columns:\n", - " raise ValueError(\"detections must have a 'frame' column\")\n", - "\n", - " from sklearn.cluster import DBSCAN\n", - "\n", - " xy = detections[[\"x\", \"y\"]].values\n", - " labels = DBSCAN(eps=spatial_eps, min_samples=1).fit_predict(xy)\n", - "\n", - " detections = detections.copy()\n", - " detections[\"source_id\"] = labels\n", - "\n", - " # ── Motion consistency check ──────────────────────────────────────\n", - " # For each stationary candidate, compute per-frame SNR-weighted\n", - " # centroid and fit a velocity. Detections that are offset from the\n", - " # time-averaged star position by more than spatial_eps are split out.\n", - " w_col = \"snr_model\" if \"snr_model\" in detections.columns else \"snr\"\n", - " weights = detections[w_col].clip(lower=1e-3).values\n", - "\n", - " moving_rows = [] # integer positional indices to demote\n", - "\n", - " for sid, idx in detections.groupby(\"source_id\").groups.items():\n", - " if sid == -1:\n", - " continue\n", - " sub = detections.loc[idx]\n", - " w = weights[idx]\n", - "\n", - " # SNR-weighted centroid (the star's expected fixed position)\n", - " w_sum = w.sum()\n", - " cx = (sub[\"x\"].values * w).sum() / w_sum\n", - " cy = (sub[\"y\"].values * w).sum() / w_sum\n", - "\n", - " # Per-frame centroid to measure drift\n", - " frames = sub[\"frame\"].values\n", - " if len(np.unique(frames)) < 2:\n", - " continue\n", - "\n", - " # Fit velocity to per-frame SNR-weighted centroids\n", - " frame_cx = {}\n", - " frame_cy = {}\n", - " for fi in np.unique(frames):\n", - " mask = frames == fi\n", - " wi = w[mask]\n", - " ws = wi.sum()\n", - " frame_cx[fi] = (sub[\"x\"].values[mask] * wi).sum() / ws\n", - " frame_cy[fi] = (sub[\"y\"].values[mask] * wi).sum() / ws\n", - "\n", - " ft = np.array(sorted(frame_cx))\n", - " fx = np.array([frame_cx[f] for f in ft])\n", - " fy = np.array([frame_cy[f] for f in ft])\n", - "\n", - " if len(ft) >= 2:\n", - " vx = np.polyfit(ft, fx, 1)[0]\n", - " vy = np.polyfit(ft, fy, 1)[0]\n", - " speed = np.hypot(vx, vy)\n", - " else:\n", - " speed = 0.0\n", - "\n", - " if speed > max_speed:\n", - " # Cluster is drifting — identify which detections are outliers\n", - " # from the star's SNR-weighted fixed position and demote them.\n", - " dist_from_star = np.hypot(sub[\"x\"].values - cx,\n", - " sub[\"y\"].values - cy)\n", - " outlier_mask = dist_from_star > spatial_eps\n", - " pos_idx = detections.index.get_indexer(idx)\n", - " moving_rows.extend(pos_idx[outlier_mask].tolist())\n", - "\n", - " if moving_rows:\n", - " iloc_arr = np.array(moving_rows)\n", - " detections.iloc[iloc_arr, detections.columns.get_loc(\"source_id\")] = -1\n", - "\n", - " # ── Event labelling ───────────────────────────────────────────────\n", - " # Within each stationary source, split detections into events by\n", - " # looking for gaps in the frame sequence larger than event_gap.\n", - " # A new event starts whenever the frame jump exceeds the threshold.\n", - " event_id_col = np.full(len(detections), np.nan)\n", - "\n", - " for sid, idx in detections.groupby(\"source_id\").groups.items():\n", - " if sid == -1:\n", - " continue\n", - " sub_frames = detections.loc[idx, \"frame\"].values\n", - " order = np.argsort(sub_frames)\n", - " sorted_idx = np.array(idx)[order]\n", - " sorted_frames = sub_frames[order]\n", - "\n", - " eid = 0\n", - " event_ids = [0]\n", - " for k in range(1, len(sorted_frames)):\n", - " if sorted_frames[k] - sorted_frames[k - 1] > event_gap:\n", - " eid += 1\n", - " event_ids.append(eid)\n", - "\n", - " event_id_col[detections.index.get_indexer(sorted_idx)] = event_ids\n", - "\n", - " detections[\"event_id\"] = event_id_col\n", - "\n", - " # ── SNR-weighted centroids for final groups ───────────────────────\n", - " x_w = np.empty(len(detections))\n", - " y_w = np.empty(len(detections))\n", - "\n", - " for sid, idx in detections.groupby(\"source_id\").groups.items():\n", - " if sid == -1:\n", - " x_w[idx] = detections.loc[idx, \"x\"].values\n", - " y_w[idx] = detections.loc[idx, \"y\"].values\n", - " continue\n", - " w = weights[idx]\n", - " w_sum = w.sum()\n", - " x_w[idx] = (detections.loc[idx, \"x\"].values * w).sum() / w_sum\n", - " y_w[idx] = (detections.loc[idx, \"y\"].values * w).sum() / w_sum\n", - "\n", - " detections[\"x_w\"] = x_w\n", - " detections[\"y_w\"] = y_w\n", - "\n", - " return detections\n", - "\n", - " def find_asteroids(self, detections: pd.DataFrame,\n", - " max_speed: float = 3.0,\n", - " min_detections: int = 3,\n", - " max_gap: int = 3,\n", - " position_tol: float = 1.5) -> tuple:\n", - " \"\"\"\n", - " Identify linearly-moving objects (asteroids) among the detections\n", - " using kinematic trail linking.\n", - "\n", - " The algorithm:\n", - " 1. Seeds trails from detections labelled source_id == -1 (singletons\n", - " from group()). If source_id is absent, all detections are used.\n", - " 2. For each seed at frame t0, finds candidate next detections in\n", - " frames t0+1 .. t0+max_gap within max_speed * gap pixels.\n", - " 3. Extends the trail forward frame by frame: predicts the next\n", - " position using the running velocity estimate, accepts detections\n", - " within position_tol pixels, up to max_gap missed frames.\n", - " 4. Scores trails by number of detections and linear-fit residual.\n", - " 5. Resolves conflicts greedily (longest trail wins); detections\n", - " claimed by a winning trail are removed from contention.\n", - "\n", - " Parameters\n", - " ----------\n", - " detections : DataFrame\n", - " Must contain 'frame', 'x', 'y' columns. Typically the output\n", - " of group().\n", - " max_speed : float\n", - " Maximum asteroid speed in pixels per frame. Default 3.0.\n", - " min_detections : int\n", - " Minimum number of detections to report a trail. Default 3.\n", - " max_gap : int\n", - " Maximum number of consecutive missed frames when extending a\n", - " trail. Default 3.\n", - " position_tol : float\n", - " Tolerance in pixels for matching a detection to a predicted\n", - " position on an existing trail. Default 1.5.\n", - "\n", - " Returns\n", - " -------\n", - " trails : DataFrame\n", - " One row per asteroid trail, columns:\n", - " trail_id, n_det, t_start, t_end, t_span,\n", - " x0, y0, vx, vy, speed,\n", - " r2_x, r2_y — R² of linear fit in each axis\n", - " det_indices — list of detection DataFrame indices\n", - " detections : DataFrame\n", - " Input detections with added 'trail_id' column\n", - " (NaN = not part of any trail).\n", - " \"\"\"\n", - " if \"frame\" not in detections.columns:\n", - " raise ValueError(\"detections must have a 'frame' column\")\n", - "\n", - " # Work only on candidate moving detections (singletons from group())\n", - " if \"source_id\" in detections.columns:\n", - " cands = detections[detections[\"source_id\"] == -1].copy()\n", - " else:\n", - " cands = detections.copy()\n", - "\n", - " if len(cands) < min_detections:\n", - " detections = detections.copy()\n", - " detections[\"trail_id\"] = np.nan\n", - " return pd.DataFrame(), detections\n", - "\n", - " cands = cands.sort_values(\"frame\").reset_index() # keeps original idx in 'index' col\n", - " # Build a per-frame index for fast lookup\n", - " frames_sorted = sorted(cands[\"frame\"].unique())\n", - " by_frame = {t: cands[cands[\"frame\"] == t] for t in frames_sorted}\n", - " frame_set = set(frames_sorted)\n", - "\n", - " from scipy.spatial import KDTree\n", - "\n", - " def _kdtree(frame_t):\n", - " sub = by_frame.get(frame_t)\n", - " if sub is None or len(sub) == 0:\n", - " return None, None\n", - " return KDTree(sub[[\"x\", \"y\"]].values), sub\n", - "\n", - " # ── Trail building ────────────────────────────────────────────────────\n", - " all_trails = [] # list of (score, [original_indices])\n", - "\n", - " used_set = set()\n", - "\n", - " for _, seed in cands.iterrows():\n", - " orig_idx = seed[\"index\"]\n", - " if orig_idx in used_set:\n", - " continue\n", - " t0 = seed[\"frame\"]\n", - " x0, y0 = seed[\"x\"], seed[\"y\"]\n", - "\n", - " # Find the best initial pair to set a starting velocity\n", - " best_pair = None\n", - " best_pair_dist = np.inf\n", - " for gap in range(1, max_gap + 1):\n", - " t1 = t0 + gap\n", - " kdt, sub1 = _kdtree(t1)\n", - " if kdt is None:\n", - " continue\n", - " search_r = max_speed * gap\n", - " idxs = kdt.query_ball_point([x0, y0], r=search_r)\n", - " for j in idxs:\n", - " row = sub1.iloc[j]\n", - " dist = np.hypot(row[\"x\"] - x0, row[\"y\"] - y0)\n", - " if dist < best_pair_dist:\n", - " best_pair_dist = dist\n", - " best_pair = (t1, row[\"x\"], row[\"y\"], row[\"index\"], gap)\n", - " if best_pair is not None:\n", - " break # prefer smallest gap\n", - "\n", - " if best_pair is None:\n", - " continue # no pair found, skip this seed\n", - "\n", - " t1, x1, y1, idx1, gap1 = best_pair\n", - " vx = (x1 - x0) / gap1\n", - " vy = (y1 - y0) / gap1\n", - "\n", - " # Extend the trail forward\n", - " chain_orig = [orig_idx, idx1]\n", - " chain_frames = [t0, t1]\n", - " chain_x = [x0, x1]\n", - " chain_y = [y0, y1]\n", - " cur_vx, cur_vy = vx, vy\n", - " cur_t = t1\n", - " cur_x, cur_y = x1, y1\n", - " consecutive_misses = 0\n", - "\n", - " while consecutive_misses <= max_gap:\n", - " cur_t += 1\n", - " if cur_t > max(frames_sorted):\n", - " break\n", - " pred_x = cur_x + cur_vx\n", - " pred_y = cur_y + cur_vy\n", - " kdt, sub_t = _kdtree(cur_t)\n", - " if kdt is None:\n", - " consecutive_misses += 1\n", - " cur_x += cur_vx\n", - " cur_y += cur_vy\n", - " continue\n", - " matches = kdt.query_ball_point([pred_x, pred_y], r=position_tol)\n", - " if not matches:\n", - " consecutive_misses += 1\n", - " cur_x += cur_vx\n", - " cur_y += cur_vy\n", - " continue\n", - " # Pick closest match\n", - " best_j = min(matches, key=lambda j: np.hypot(\n", - " sub_t.iloc[j][\"x\"] - pred_x,\n", - " sub_t.iloc[j][\"y\"] - pred_y))\n", - " row = sub_t.iloc[best_j]\n", - " chain_orig.append(row[\"index\"])\n", - " chain_frames.append(cur_t)\n", - " chain_x.append(row[\"x\"])\n", - " chain_y.append(row[\"y\"])\n", - " # Update running velocity (exponential moving avg)\n", - " dt = cur_t - chain_frames[-2]\n", - " new_vx = (row[\"x\"] - chain_x[-2]) / dt\n", - " new_vy = (row[\"y\"] - chain_y[-2]) / dt\n", - " cur_vx = 0.7 * cur_vx + 0.3 * new_vx\n", - " cur_vy = 0.7 * cur_vy + 0.3 * new_vy\n", - " cur_x, cur_y = row[\"x\"], row[\"y\"]\n", - " consecutive_misses = 0\n", - "\n", - " if len(chain_orig) < min_detections:\n", - " continue\n", - "\n", - " # Linear fit quality\n", - " frames_arr = np.array(chain_frames, dtype=float)\n", - " x_arr = np.array(chain_x)\n", - " y_arr = np.array(chain_y)\n", - " r2_x = _r2(frames_arr, x_arr)\n", - " r2_y = _r2(frames_arr, y_arr)\n", - "\n", - " score = len(chain_orig) + 0.5 * (r2_x + r2_y)\n", - " all_trails.append((score, chain_orig, chain_frames, chain_x, chain_y,\n", - " r2_x, r2_y))\n", - "\n", - " # ── Conflict resolution: greedy, longest trail wins ───────────────────\n", - " all_trails.sort(key=lambda t: -t[0])\n", - " claimed = set()\n", - " selected = []\n", - " for trail in all_trails:\n", - " score, orig_idxs, frms, xs, ys, r2x, r2y = trail\n", - " # Skip if too many detections already claimed\n", - " overlap = sum(1 for i in orig_idxs if i in claimed)\n", - " if overlap > len(orig_idxs) * 0.5:\n", - " continue\n", - " for i in orig_idxs:\n", - " claimed.add(i)\n", - " selected.append(trail)\n", - "\n", - " # ── Build trail catalog ───────────────────────────────────────────────\n", - " trail_rows = []\n", - " trail_id_map = {} # orig detection index → trail_id\n", - "\n", - " for tid, (score, orig_idxs, frms, xs, ys, r2x, r2y) in enumerate(selected):\n", - " frames_arr = np.array(frms, dtype=float)\n", - " x_arr = np.array(xs)\n", - " y_arr = np.array(ys)\n", - " vx_fit, x0_fit = np.polyfit(frames_arr, x_arr, 1)\n", - " vy_fit, y0_fit = np.polyfit(frames_arr, y_arr, 1)\n", - " t_ref = frames_arr[0]\n", - " trail_rows.append({\n", - " \"trail_id\": tid,\n", - " \"n_det\": len(orig_idxs),\n", - " \"t_start\": int(frms[0]),\n", - " \"t_end\": int(frms[-1]),\n", - " \"t_span\": int(frms[-1]) - int(frms[0]) + 1,\n", - " \"x0\": float(x0_fit + vx_fit * t_ref),\n", - " \"y0\": float(y0_fit + vy_fit * t_ref),\n", - " \"vx\": float(vx_fit),\n", - " \"vy\": float(vy_fit),\n", - " \"speed\": float(np.hypot(vx_fit, vy_fit)),\n", - " \"r2_x\": float(r2x),\n", - " \"r2_y\": float(r2y),\n", - " \"det_indices\": orig_idxs,\n", - " })\n", - " for i in orig_idxs:\n", - " trail_id_map[i] = tid\n", - "\n", - " trails_df = pd.DataFrame(trail_rows) if trail_rows else pd.DataFrame(\n", - " columns=[\"trail_id\", \"n_det\", \"t_start\", \"t_end\", \"t_span\",\n", - " \"x0\", \"y0\", \"vx\", \"vy\", \"speed\", \"r2_x\", \"r2_y\", \"det_indices\"])\n", - "\n", - " detections = detections.copy()\n", - " detections[\"trail_id\"] = detections.index.map(trail_id_map)\n", - "\n", - " return trails_df, detections\n", - "\n", - " @property\n", - " def background(self):\n", - " \"\"\"Background object from the last call to find(). None if not yet called.\"\"\"\n", - " return getattr(self, \"background_\", None)\n", - "\n", - " # ── internals ─────────────────────────────────────────────────────────────\n", - "\n", - " def _find_single(self, image: np.ndarray) -> pd.DataFrame:\n", - " \"\"\"Run multi-scale SEP detection on a single 2-D image.\"\"\"\n", - " data = np.asarray(image, dtype=np.float64)\n", - " bkg = sep.Background(data, bw=self.bw, bh=self.bw)\n", - " data_sub = data - bkg.back()\n", - "\n", - " if self.ref is not None:\n", - " err = self._noise_map(bkg)\n", - " else:\n", - " err = bkg.rms()\n", - "\n", - " per_scale = []\n", - " for fwhm, kern in zip(self._fwhms, self._kernels):\n", - " try:\n", - " objs = sep.extract(\n", - " data_sub,\n", - " thresh=self.thresh,\n", - " err=err,\n", - " minarea=2,\n", - " deblend_nthresh=self.deblend_nthresh,\n", - " deblend_cont=self.deblend_cont,\n", - " filter_kernel=kern,\n", - " )\n", - " except Exception:\n", - " continue\n", - " if len(objs) == 0:\n", - " continue\n", - " df = pd.DataFrame({\n", - " \"x\": objs[\"x\"],\n", - " \"y\": objs[\"y\"],\n", - " \"flux\": objs[\"flux\"],\n", - " \"peak\": objs[\"peak\"],\n", - " \"a\": objs[\"a\"],\n", - " \"b\": objs[\"b\"],\n", - " \"theta\": objs[\"theta\"],\n", - " \"flag\": objs[\"flag\"],\n", - " \"detection_fwhm\": fwhm,\n", - " })\n", - " per_scale.append(df)\n", - "\n", - " if not per_scale:\n", - " return pd.DataFrame(columns=[\"x\", \"y\", \"flux\", \"peak\", \"a\", \"b\",\n", - " \"theta\", \"flag\", \"detection_fwhm\",\n", - " \"snr\", \"ellipticity\"])\n", - "\n", - " combined = (\n", - " pd.concat(per_scale, ignore_index=True)\n", - " .sort_values(\"flux\", ascending=False)\n", - " .reset_index(drop=True)\n", - " )\n", - "\n", - " sources = self._dedup(combined)\n", - "\n", - " # ── SNR via circular aperture photometry (r = 1.5 px) ─────────────\n", - " ap_flux, ap_err, _ = sep.sum_circle(\n", - " data_sub, sources[\"x\"].values, sources[\"y\"].values,\n", - " r=1.5, err=err, gain=1.0,\n", - " )\n", - " ap_err = np.where(ap_err > 0, ap_err, np.nan)\n", - " sources[\"snr\"] = ap_flux / ap_err\n", - "\n", - " # ── snr_model: ref-scaled noise normalisation ─────────────────────\n", - " if self.ref is not None:\n", - " noise_map = self._noise_map(bkg)\n", - " xi = np.round(sources[\"x\"].values).astype(int).clip(0, data.shape[1] - 1)\n", - " yi = np.round(sources[\"y\"].values).astype(int).clip(0, data.shape[0] - 1)\n", - " sources[\"snr_model\"] = sources[\"peak\"].values / noise_map[yi, xi]\n", - "\n", - " # ── Ellipticity ────────────────────────────────────────────────────\n", - " a = sources[\"a\"].values.clip(min=1e-6)\n", - " sources[\"ellipticity\"] = 1.0 - sources[\"b\"].values / a\n", - "\n", - " # ── Negative pixel extent ──────────────────────────────────────────\n", - " sources[\"neg_extent\"] = self._neg_pixel_extent(data_sub, sources, r=2.0)\n", - "\n", - " self.background_ = bkg\n", - " return sources\n", - "\n", - " def _find_cube(self, cube: np.ndarray) -> pd.DataFrame:\n", - " \"\"\"Run _find_single on each frame in parallel using joblib.\"\"\"\n", - " from joblib import Parallel, delayed\n", - "\n", - " T = cube.shape[0]\n", - " results = Parallel(n_jobs=-1, prefer=\"threads\")(\n", - " delayed(self._find_single)(cube[t]) for t in range(T)\n", - " )\n", - "\n", - " frames = []\n", - " for t, df in enumerate(results):\n", - " if len(df) > 0:\n", - " df = df.copy()\n", - " df[\"frame\"] = t\n", - " frames.append(df)\n", - "\n", - " if not frames:\n", - " return pd.DataFrame()\n", - " return pd.concat(frames, ignore_index=True)\n", - "\n", - " def _noise_map(self, bkg) -> np.ndarray:\n", - " \"\"\"\n", - " Build a per-pixel noise map combining background RMS and the\n", - " ref-scaled systematic residual:\n", - "\n", - " noise[y,x] = sqrt(bkg_rms[y,x]² + (k * ref[y,x])²)\n", - " \"\"\"\n", - " bkg_rms = bkg.rms()\n", - " if self.residual_k is not None:\n", - " k = self.residual_k\n", - " else:\n", - " from astropy.stats import sigma_clipped_stats\n", - " m, med, std = sigma_clipped_stats(self.ref)\n", - " bright = self.ref > 5 * med\n", - " if bright.sum() > 10:\n", - " k = float(np.median(bkg_rms[bright] / self.ref[bright]))\n", - " else:\n", - " k = 0.0078 # TESS default measured from sector 38\n", - " from astropy.stats import sigma_clipped_stats\n", - " m, med, std = sigma_clipped_stats(self.ref)\n", - " bright = self.ref < 3*std + med\n", - " ref_err = self.ref.copy()\n", - " ref_err[bright] = 1\n", - " return np.sqrt(bkg_rms**2 + 0.1*ref_err)\n", - "\n", - " @staticmethod\n", - " def _neg_pixel_extent(data_sub: np.ndarray, sources: pd.DataFrame,\n", - " r: float = 1.5, box: int = 1) -> np.ndarray:\n", - " \"\"\"\n", - " For each source, return the ratio of the most-negative pixel\n", - " to the background stddev within a circular aperture of radius\n", - " `r`, floored at zero.\n", - "\n", - " neg_extent = max(0, -min(pixels_in_aperture))/std\n", - " \"\"\"\n", - " from astropy.stats import sigma_clipped_stats\n", - " m, med, std = sigma_clipped_stats(data_sub)\n", - " H, W = data_sub.shape\n", - " R = int(np.ceil(r))\n", - " dy, dx = np.mgrid[-R:R+1, -R:R+1]\n", - " in_circle = (dx**2 + dy**2) <= r**2\n", - " dy_offsets = dy[in_circle]\n", - " dx_offsets = dx[in_circle]\n", - "\n", - " xs = np.round(sources[\"x\"].values).astype(int)\n", - " ys = np.round(sources[\"y\"].values).astype(int)\n", - "\n", - " extents = np.empty(len(sources), dtype=float)\n", - " for i, (cx, cy) in enumerate(zip(xs, ys)):\n", - " px = cx + dx_offsets\n", - " py = cy + dy_offsets\n", - " valid = (px >= 0) & (px < W) & (py >= 0) & (py < H)\n", - " if valid.sum() == 0:\n", - " extents[i] = np.nan\n", - " continue\n", - "\n", - " y0 = max(0, ys[i] - box); y1 = min(H, ys[i] + box + 1)\n", - " x0 = max(0, xs[i] - box); x1 = min(W, xs[i] + box + 1)\n", - " patch = data_sub[y0:y1, x0:x1]\n", - " if patch.size == 0:\n", - " extents[i] = np.nan\n", - " continue\n", - " extents[i] = max(0.0, -float(patch.min())) / std\n", - "\n", - " return extents\n", - "\n", - " @staticmethod\n", - " def _mexhat(fwhm: float) -> np.ndarray:\n", - " \"\"\"Mexican-hat (Laplacian-of-Gaussian) kernel normalised to unit abs-sum.\"\"\"\n", - " sigma = fwhm / (2 * np.sqrt(2 * np.log(2)))\n", - " size = max(5, int(np.ceil(6 * sigma)) | 1)\n", - " c = size // 2\n", - " y, x = np.mgrid[-c:c+1, -c:c+1]\n", - " r2 = (x**2 + y**2) / (2 * sigma**2)\n", - " k = (1 - r2) * np.exp(-r2)\n", - " return (k / np.abs(k).sum()).astype(np.float32)\n", - "\n", - " def _dedup(self, combined: pd.DataFrame) -> pd.DataFrame:\n", - " \"\"\"Remove duplicate detections within dedup_radius, keeping highest flux.\"\"\"\n", - " from scipy.spatial import KDTree\n", - " keep = np.ones(len(combined), dtype=bool)\n", - " tree = KDTree(combined[[\"x\", \"y\"]].values)\n", - " for i in range(len(combined)):\n", - " if not keep[i]:\n", - " continue\n", - " for j in tree.query_ball_point(combined[[\"x\", \"y\"]].iloc[i].values,\n", - " r=self.dedup_radius):\n", - " if j > i:\n", - " keep[j] = False\n", - " return combined[keep].reset_index(drop=True)\n", - "\n", - "\n", - "# ── helpers ───────────────────────────────────────────────────────────────────\n", - "\n", - "def _r2(x: np.ndarray, y: np.ndarray) -> float:\n", - " \"\"\"R² of a linear fit y ~ x. Returns 0 if fewer than 2 points.\"\"\"\n", - " if len(x) < 2 or np.ptp(x) == 0:\n", - " return 0.0\n", - " coeffs = np.polyfit(x, y, 1)\n", - " y_pred = np.polyval(coeffs, x)\n", - " ss_res = np.sum((y - y_pred) ** 2)\n", - " ss_tot = np.sum((y - y.mean()) ** 2)\n", - " return float(1.0 - ss_res / ss_tot) if ss_tot > 0 else 1.0\n" - ] - }, - { - "cell_type": "code", - "execution_count": 447, - "id": "7b019326", - "metadata": {}, - "outputs": [], - "source": [ - "finder = TESSSourceFinder(ref=tess.ref)\n", - "sources = finder.find(tess.flux)\n", - "good = finder.filter(sources)\n", - "grouped = finder.group(filtered)" - ] - }, - { - "cell_type": "code", - "execution_count": 448, - "id": "049a7a1d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
xyfluxpeakabthetaflagdetection_fwhmsnrsnr_modelellipticityneg_extentframesource_idevent_idx_wy_w
034.85108621.4772132201.75366249.64339111.3108038.016147-1.03725520.8444442.02227616.6368850.2912841.803149000.034.85108621.477213
134.83054717.2274422016.61596749.64339111.1934688.1840030.74423320.9888892.57625716.5960000.2688590.814586010.031.89677118.101201
223.79753344.777055165.73448211.0460214.5870701.941225-0.62054821.2777782.1769083.6602130.5768051.740357020.021.45527929.887541
342.8914688.420636156.50607333.7995681.5002160.8214711.51294811.1333332.9895676.0529220.4524315.281168030.040.94501014.144728
423.20649623.014917121.08476325.6784731.7717711.488228-1.29909911.7111114.2266446.0608510.1600341.329672020.021.45527929.887541
.........................................................
2964411.19993335.74040824.7052639.0086870.9428030.496735-0.49640201.7111113.97836111.1341380.4731290.50117333701660.09.76459837.490497
2964510.5662630.25680714.6164726.9940630.9531660.4813640.55677422.0000002.2158227.3412280.4949842.9674893370648.010.5937731.738362
296462.2103608.93641545.8757599.1037020.9765320.8952780.63635810.7000005.45552610.2954240.0832060.000000337149.01.54131613.051185
2964744.15044026.58371412.9041894.3345281.0995430.4403610.52133501.8555562.6077204.8487710.5995060.6129283371950.044.15044026.583714
2964823.66036138.6055258.0725602.3677960.7670090.462033-1.15221211.8555562.0917842.9900250.3976162.907335337122.021.45527929.887541
\n", - "

29649 rows × 18 columns

\n", - "
" - ], - "text/plain": [ - " x y flux peak a b \\\n", - "0 34.851086 21.477213 2201.753662 49.643391 11.310803 8.016147 \n", - "1 34.830547 17.227442 2016.615967 49.643391 11.193468 8.184003 \n", - "2 23.797533 44.777055 165.734482 11.046021 4.587070 1.941225 \n", - "3 42.891468 8.420636 156.506073 33.799568 1.500216 0.821471 \n", - "4 23.206496 23.014917 121.084763 25.678473 1.771771 1.488228 \n", - "... ... ... ... ... ... ... \n", - "29644 11.199933 35.740408 24.705263 9.008687 0.942803 0.496735 \n", - "29645 10.566263 0.256807 14.616472 6.994063 0.953166 0.481364 \n", - "29646 2.210360 8.936415 45.875759 9.103702 0.976532 0.895278 \n", - "29647 44.150440 26.583714 12.904189 4.334528 1.099543 0.440361 \n", - "29648 23.660361 38.605525 8.072560 2.367796 0.767009 0.462033 \n", - "\n", - " theta flag detection_fwhm snr snr_model ellipticity \\\n", - "0 -1.037255 2 0.844444 2.022276 16.636885 0.291284 \n", - "1 0.744233 2 0.988889 2.576257 16.596000 0.268859 \n", - "2 -0.620548 2 1.277778 2.176908 3.660213 0.576805 \n", - "3 1.512948 1 1.133333 2.989567 6.052922 0.452431 \n", - "4 -1.299099 1 1.711111 4.226644 6.060851 0.160034 \n", - "... ... ... ... ... ... ... \n", - "29644 -0.496402 0 1.711111 3.978361 11.134138 0.473129 \n", - "29645 0.556774 2 2.000000 2.215822 7.341228 0.494984 \n", - "29646 0.636358 1 0.700000 5.455526 10.295424 0.083206 \n", - "29647 0.521335 0 1.855556 2.607720 4.848771 0.599506 \n", - "29648 -1.152212 1 1.855556 2.091784 2.990025 0.397616 \n", - "\n", - " neg_extent frame source_id event_id x_w y_w \n", - "0 1.803149 0 0 0.0 34.851086 21.477213 \n", - "1 0.814586 0 1 0.0 31.896771 18.101201 \n", - "2 1.740357 0 2 0.0 21.455279 29.887541 \n", - "3 5.281168 0 3 0.0 40.945010 14.144728 \n", - "4 1.329672 0 2 0.0 21.455279 29.887541 \n", - "... ... ... ... ... ... ... \n", - "29644 0.501173 3370 16 60.0 9.764598 37.490497 \n", - "29645 2.967489 3370 6 48.0 10.593773 1.738362 \n", - "29646 0.000000 3371 4 9.0 1.541316 13.051185 \n", - "29647 0.612928 3371 95 0.0 44.150440 26.583714 \n", - "29648 2.907335 3371 2 2.0 21.455279 29.887541 \n", - "\n", - "[29649 rows x 18 columns]" - ] - }, - "execution_count": 448, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "grouped" - ] - }, - { - "cell_type": "code", - "execution_count": 445, - "id": "072a6fd2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
xyfluxpeakabthetaflagdetection_fwhmsnrsnr_modelellipticityneg_extent
025.21702924.8716324.2131714.5462591.6247271.284016-1.06510110.72.3632495.4368710.2097040.807511
\n", - "
" - ], - "text/plain": [ - " x y flux peak a b theta \\\n", - "0 25.217029 24.87163 24.213171 4.546259 1.624727 1.284016 -1.065101 \n", - "\n", - " flag detection_fwhm snr snr_model ellipticity neg_extent \n", - "0 1 0.7 2.363249 5.436871 0.209704 0.807511 " - ] - }, - "execution_count": 445, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "j = 2770\n", - "sources = finder.find(tess.flux[j])\n", - "good = finder.filter(sources)\n", - "good" - ] - }, - { - "cell_type": "code", - "execution_count": 446, - "id": "5f3edc7c", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 446, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[j],vmax=10,vmin=-10,origin='lower')\n", - "plt.scatter(sources['x'],sources['y'])\n", - "#good = sources[sources['snr'] > 2]\n", - "plt.scatter(good['x'],good['y'])\n", - "plt.colorbar()" - ] - }, - { - "cell_type": "code", - "execution_count": 352, - "id": "bc1fa4ba", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
xyfluxpeakabthetaflagdetection_fwhmsnrsnr_modelellipticityneg_extent
73.0222478.46007361.56281712.6592151.357469NaN-1.523636102.0000003.36411712.633935NaN0.000000
230.0000009.50937128.5215594.2906191.8178160.6644741.132521111.1333332.9712884.3295860.6344660.000000
3925.10347024.93188718.3820253.8529591.000451NaN-0.95275991.8555562.9511443.435887NaN0.000000
422.45559010.54441017.6858164.2906191.0135540.389418-0.39737690.9888892.8719444.2573620.6157902.320739
\n", - "
" - ], - "text/plain": [ - " x y flux peak a b theta \\\n", - "7 3.022247 8.460073 61.562817 12.659215 1.357469 NaN -1.523636 \n", - "23 0.000000 9.509371 28.521559 4.290619 1.817816 0.664474 1.132521 \n", - "39 25.103470 24.931887 18.382025 3.852959 1.000451 NaN -0.952759 \n", - "42 2.455590 10.544410 17.685816 4.290619 1.013554 0.389418 -0.397376 \n", - "\n", - " flag detection_fwhm snr snr_model ellipticity neg_extent \n", - "7 10 2.000000 3.364117 12.633935 NaN 0.000000 \n", - "23 11 1.133333 2.971288 4.329586 0.634466 0.000000 \n", - "39 9 1.855556 2.951144 3.435887 NaN 0.000000 \n", - "42 9 0.988889 2.871944 4.257362 0.615790 2.320739 " - ] - }, - "execution_count": 352, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "good" - ] - }, - { - "cell_type": "code", - "execution_count": 309, - "id": "d697f3af", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 309, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.flux[:,9,2])" - ] - }, - { - "cell_type": "code", - "execution_count": 310, - "id": "9d7c8d13", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
xyfluxpeakabthetaflagdetection_fwhmsnrsnr_modelellipticityneg_extent
1624.86035124.79018840.8028075.6605302.3832941.519862-1.18700010.72.4657254.9053950.3622850.217271
192.3364938.49119233.98917811.8584821.3098450.757789-0.50908710.72.1847471.4907650.4214671.223391
\n", - "
" - ], - "text/plain": [ - " x y flux peak a b theta \\\n", - "16 24.860351 24.790188 40.802807 5.660530 2.383294 1.519862 -1.187000 \n", - "19 2.336493 8.491192 33.989178 11.858482 1.309845 0.757789 -0.509087 \n", - "\n", - " flag detection_fwhm snr snr_model ellipticity neg_extent \n", - "16 1 0.7 2.465725 4.905395 0.362285 0.217271 \n", - "19 1 0.7 2.184747 1.490765 0.421467 1.223391 " - ] - }, - "execution_count": 310, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sources[sources['snr'] > 2]" - ] - }, - { - "cell_type": "code", - "execution_count": 249, - "id": "64fa8887", - "metadata": {}, - "outputs": [], - "source": [ - "filtered = finder.filter(sources) \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "45b1ef61", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 250, - "id": "c43c8c86", - "metadata": {}, - "outputs": [], - "source": [ - "grouped = finder.group(filtered)" - ] - }, - { - "cell_type": "code", - "execution_count": 252, - "id": "fa4671d4", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
xyfluxpeakabthetaflagdetection_fwhmsnrsnr_modelellipticityneg_extentframesource_idevent_idx_wy_w
423.20649623.014917121.08476325.6784731.7717711.488228-1.29909911.7111114.2266446.0608510.1600341.329672020.021.45527929.887541
1323.06119224.617786157.07194530.4721221.9529691.292140-1.20978110.7000004.97620210.5551810.3383711.350902220.021.45527929.887541
1826.37216126.28577982.67817713.5276591.2107750.6928261.33036510.7000005.1213644.7598410.4277830.000000220.021.45527929.887541
2324.28447824.406086227.79278628.6463782.1962071.7920501.29037310.7000004.6742729.6930610.1840251.772299320.021.45527929.887541
2623.26645023.707886165.16262828.6463782.0703631.378026-1.46056310.8444444.4418068.3823380.3344041.772299320.021.45527929.887541
.........................................................
2699125.45171924.78320514.5189953.4132642.1328000.879731-0.58102310.8444442.3667904.0778870.5875230.190202278520.021.45527929.887541
2803423.12300423.19933313.6252754.0913391.2929000.590509-0.13492911.8555562.2982483.9565720.5432684.273107291420.021.45527929.887541
2865423.36314523.08435411.2008372.8547411.2720830.705342-0.69416411.8555562.2135672.7516640.4455225.152234299820.021.45527929.887541
2913323.52690823.07430816.8535982.4811511.7209981.121005-0.22989510.7000002.1870723.5385120.3486311.407833312720.021.45527929.887541
2949323.58915825.22344012.4149203.2552161.6078260.986555-0.77698210.8444442.0954584.5989160.3864051.878872328621.021.45527929.887541
\n", - "

186 rows × 18 columns

\n", - "
" - ], - "text/plain": [ - " x y flux peak a b \\\n", - "4 23.206496 23.014917 121.084763 25.678473 1.771771 1.488228 \n", - "13 23.061192 24.617786 157.071945 30.472122 1.952969 1.292140 \n", - "18 26.372161 26.285779 82.678177 13.527659 1.210775 0.692826 \n", - "23 24.284478 24.406086 227.792786 28.646378 2.196207 1.792050 \n", - "26 23.266450 23.707886 165.162628 28.646378 2.070363 1.378026 \n", - "... ... ... ... ... ... ... \n", - "26991 25.451719 24.783205 14.518995 3.413264 2.132800 0.879731 \n", - "28034 23.123004 23.199333 13.625275 4.091339 1.292900 0.590509 \n", - "28654 23.363145 23.084354 11.200837 2.854741 1.272083 0.705342 \n", - "29133 23.526908 23.074308 16.853598 2.481151 1.720998 1.121005 \n", - "29493 23.589158 25.223440 12.414920 3.255216 1.607826 0.986555 \n", - "\n", - " theta flag detection_fwhm snr snr_model ellipticity \\\n", - "4 -1.299099 1 1.711111 4.226644 6.060851 0.160034 \n", - "13 -1.209781 1 0.700000 4.976202 10.555181 0.338371 \n", - "18 1.330365 1 0.700000 5.121364 4.759841 0.427783 \n", - "23 1.290373 1 0.700000 4.674272 9.693061 0.184025 \n", - "26 -1.460563 1 0.844444 4.441806 8.382338 0.334404 \n", - "... ... ... ... ... ... ... \n", - "26991 -0.581023 1 0.844444 2.366790 4.077887 0.587523 \n", - "28034 -0.134929 1 1.855556 2.298248 3.956572 0.543268 \n", - "28654 -0.694164 1 1.855556 2.213567 2.751664 0.445522 \n", - "29133 -0.229895 1 0.700000 2.187072 3.538512 0.348631 \n", - "29493 -0.776982 1 0.844444 2.095458 4.598916 0.386405 \n", - "\n", - " neg_extent frame source_id event_id x_w y_w \n", - "4 1.329672 0 2 0.0 21.455279 29.887541 \n", - "13 1.350902 2 2 0.0 21.455279 29.887541 \n", - "18 0.000000 2 2 0.0 21.455279 29.887541 \n", - "23 1.772299 3 2 0.0 21.455279 29.887541 \n", - "26 1.772299 3 2 0.0 21.455279 29.887541 \n", - "... ... ... ... ... ... ... \n", - "26991 0.190202 2785 2 0.0 21.455279 29.887541 \n", - "28034 4.273107 2914 2 0.0 21.455279 29.887541 \n", - "28654 5.152234 2998 2 0.0 21.455279 29.887541 \n", - "29133 1.407833 3127 2 0.0 21.455279 29.887541 \n", - "29493 1.878872 3286 2 1.0 21.455279 29.887541 \n", - "\n", - "[186 rows x 18 columns]" - ] - }, - "execution_count": 252, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "grouped[(grouped['x'] > 23) & (grouped['x'] < 27) & (grouped['y'] > 23) & (grouped['y'] < 27)]" - ] - }, - { - "cell_type": "code", - "execution_count": 456, - "id": "80d3f0be", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
xyfluxpeakabthetaflagdetection_fwhmsnrsnr_modelellipticityneg_extentframesource_idevent_idx_wy_w
034.85108621.4772132201.75366249.64339111.3108038.016147-1.03725520.8444442.02227616.6368850.2912841.803149000.034.85108621.477213
134.83054717.2274422016.61596749.64339111.1934688.1840030.74423320.9888892.57625716.5960000.2688590.814586010.031.89677118.101201
223.79753344.777055165.73448211.0460214.5870701.941225-0.62054821.2777782.1769083.6602130.5768051.740357020.021.45527929.887541
342.8914688.420636156.50607333.7995681.5002160.8214711.51294811.1333332.9895676.0529220.4524315.281168030.040.94501014.144728
423.20649623.014917121.08476325.6784731.7717711.488228-1.29909911.7111114.2266446.0608510.1600341.329672020.021.45527929.887541
.........................................................
2964411.19993335.74040824.7052639.0086870.9428030.496735-0.49640201.7111113.97836111.1341380.4731290.50117333701660.09.76459837.490497
2964510.5662630.25680714.6164726.9940630.9531660.4813640.55677422.0000002.2158227.3412280.4949842.9674893370648.010.5937731.738362
296462.2103608.93641545.8757599.1037020.9765320.8952780.63635810.7000005.45552610.2954240.0832060.000000337149.01.54131613.051185
2964744.15044026.58371412.9041894.3345281.0995430.4403610.52133501.8555562.6077204.8487710.5995060.6129283371950.044.15044026.583714
2964823.66036138.6055258.0725602.3677960.7670090.462033-1.15221211.8555562.0917842.9900250.3976162.907335337122.021.45527929.887541
\n", - "

29649 rows × 18 columns

\n", - "
" - ], - "text/plain": [ - " x y flux peak a b \\\n", - "0 34.851086 21.477213 2201.753662 49.643391 11.310803 8.016147 \n", - "1 34.830547 17.227442 2016.615967 49.643391 11.193468 8.184003 \n", - "2 23.797533 44.777055 165.734482 11.046021 4.587070 1.941225 \n", - "3 42.891468 8.420636 156.506073 33.799568 1.500216 0.821471 \n", - "4 23.206496 23.014917 121.084763 25.678473 1.771771 1.488228 \n", - "... ... ... ... ... ... ... \n", - "29644 11.199933 35.740408 24.705263 9.008687 0.942803 0.496735 \n", - "29645 10.566263 0.256807 14.616472 6.994063 0.953166 0.481364 \n", - "29646 2.210360 8.936415 45.875759 9.103702 0.976532 0.895278 \n", - "29647 44.150440 26.583714 12.904189 4.334528 1.099543 0.440361 \n", - "29648 23.660361 38.605525 8.072560 2.367796 0.767009 0.462033 \n", - "\n", - " theta flag detection_fwhm snr snr_model ellipticity \\\n", - "0 -1.037255 2 0.844444 2.022276 16.636885 0.291284 \n", - "1 0.744233 2 0.988889 2.576257 16.596000 0.268859 \n", - "2 -0.620548 2 1.277778 2.176908 3.660213 0.576805 \n", - "3 1.512948 1 1.133333 2.989567 6.052922 0.452431 \n", - "4 -1.299099 1 1.711111 4.226644 6.060851 0.160034 \n", - "... ... ... ... ... ... ... \n", - "29644 -0.496402 0 1.711111 3.978361 11.134138 0.473129 \n", - "29645 0.556774 2 2.000000 2.215822 7.341228 0.494984 \n", - "29646 0.636358 1 0.700000 5.455526 10.295424 0.083206 \n", - "29647 0.521335 0 1.855556 2.607720 4.848771 0.599506 \n", - "29648 -1.152212 1 1.855556 2.091784 2.990025 0.397616 \n", - "\n", - " neg_extent frame source_id event_id x_w y_w \n", - "0 1.803149 0 0 0.0 34.851086 21.477213 \n", - "1 0.814586 0 1 0.0 31.896771 18.101201 \n", - "2 1.740357 0 2 0.0 21.455279 29.887541 \n", - "3 5.281168 0 3 0.0 40.945010 14.144728 \n", - "4 1.329672 0 2 0.0 21.455279 29.887541 \n", - "... ... ... ... ... ... ... \n", - "29644 0.501173 3370 16 60.0 9.764598 37.490497 \n", - "29645 2.967489 3370 6 48.0 10.593773 1.738362 \n", - "29646 0.000000 3371 4 9.0 1.541316 13.051185 \n", - "29647 0.612928 3371 95 0.0 44.150440 26.583714 \n", - "29648 2.907335 3371 2 2.0 21.455279 29.887541 \n", - "\n", - "[29649 rows x 18 columns]" - ] - }, - "execution_count": 456, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "grouped" - ] - }, - { - "cell_type": "code", - "execution_count": 457, - "id": "a6d2e2ea", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 457, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.ref,vmax=50,vmin=0,cmap='gray')\n", - "plt.scatter(grouped['x'],grouped['y'],c=grouped['source_id'])\n", - "plt.colorbar()" - ] - }, - { - "cell_type": "code", - "execution_count": 455, - "id": "3fba88e6", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 455, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.flux[:,34,16])" - ] - }, - { - "cell_type": "code", - "execution_count": 230, - "id": "20c5b0bd", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 230, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "j = 2783\n", - "finder = TESSSourceFinder()\n", - "sources = finder.find(tess.flux[j])\n", - "clean = sources[(sources.snr > 2) & (sources.neg_extent < 3)]\n", - "plt.figure()\n", - "plt.imshow(tess.flux[j],vmax=5,vmin=-5)\n", - "plt.plot(clean['x'],clean['y'],'C1x')" - ] - }, - { - "cell_type": "code", - "execution_count": 236, - "id": "50d5fc1e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "18.05439372640169" - ] - }, - "execution_count": 236, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "-2.5*np.log10(9)+20.44" - ] - }, - { - "cell_type": "code", - "execution_count": 234, - "id": "31017f43", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 234, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.lc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 165, - "id": "79e728e7", - "metadata": {}, - "outputs": [], - "source": [ - "s = None\n", - "for i in range(len(tess.flux)):\n", - " sources = finder.find(tess.flux[i])\n", - " sources['frame'] = i\n", - " clean = sources[(sources.snr > 2) & (sources.neg_extent < 3)]\n", - " if i ==0:\n", - " s = clean\n", - " else:\n", - " s = pd.concat([s,clean])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6654ed5f", - "metadata": {}, - "outputs": [], - "source": [ - "plt.figure()\n", - "plt.hist(s['frame'])" - ] - }, - { - "cell_type": "code", - "execution_count": 196, - "id": "812b4059", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "(array([ 83., 150., 173., 189., 158., 117., 120., 116., 59., 12.]),\n", - " array([0.01834178, 0.11228404, 0.2062263 , 0.30016856, 0.39411083,\n", - " 0.48805309, 0.58199535, 0.67593761, 0.76987987, 0.86382214,\n", - " 0.9577644 ]),\n", - " )" - ] - }, - "execution_count": 196, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.hist(good.ellipticity)" - ] - }, - { - "cell_type": "code", - "execution_count": 199, - "id": "c4bd2387", - "metadata": {}, - "outputs": [], - "source": [ - "good = s[(s['frame'] > 100) & (s.neg_extent < 1) &(s.snr >= 2) & (s.ellipticity < 0.5)]" - ] - }, - { - "cell_type": "code", - "execution_count": 239, - "id": "50f75ef8", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 239, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[2570]-tess.r,vmax=50,cmap='gray')\n", - "plt.scatter(good['x'],good['y'],marker='x',c=good['frame'])\n", - "plt.colorbar()" - ] - }, - { - "cell_type": "code", - "execution_count": 238, - "id": "766291f7", - "metadata": {}, - "outputs": [], - "source": [ - "! open ." - ] - }, - { - "cell_type": "code", - "execution_count": 237, - "id": "b9c80d57", - "metadata": {}, - "outputs": [], - "source": [ - "np.save('test_diffim.npy',tess.flux)\n", - "np.save('test_diffim_ref.npy',tess.ref)" - ] - }, - { - "cell_type": "code", - "execution_count": 192, - "id": "79592b26", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 192, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.flux[:,19,27])" - ] - }, - { - "cell_type": "code", - "execution_count": 191, - "id": "b3b4e9e5", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 191, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[1750])" - ] - }, - { - "cell_type": "code", - "execution_count": 182, - "id": "86532171", - "metadata": {}, - "outputs": [], - "source": [ - "good = good.rename(columns={'x':'xcentroid','y':'ycentroid'})" - ] - }, - { - "cell_type": "code", - "execution_count": 202, - "id": "d9e2c6c9", - "metadata": {}, - "outputs": [ - { - "ename": "TypeError", - "evalue": "'float' object cannot be interpreted as an integer", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[202], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m j \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m2000\u001b[39m\u001b[38;5;66;03m#2783\u001b[39;00m\n\u001b[1;32m 2\u001b[0m finder \u001b[38;5;241m=\u001b[39m TESSSourceFinder()\n\u001b[0;32m----> 3\u001b[0m sources \u001b[38;5;241m=\u001b[39m \u001b[43mfinder\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfind\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[43mtess\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mflux\u001b[49m\u001b[43m[\u001b[49m\u001b[43mj\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4\u001b[0m clean \u001b[38;5;241m=\u001b[39m sources[(sources\u001b[38;5;241m.\u001b[39msnr \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m2\u001b[39m) \u001b[38;5;241m&\u001b[39m (sources\u001b[38;5;241m.\u001b[39mneg_extent \u001b[38;5;241m<\u001b[39m \u001b[38;5;241m3\u001b[39m)]\n\u001b[1;32m 5\u001b[0m plt\u001b[38;5;241m.\u001b[39mfigure()\n", - "Cell \u001b[0;32mIn[201], line 162\u001b[0m, in \u001b[0;36mTESSSourceFinder.find\u001b[0;34m(self, image)\u001b[0m\n\u001b[1;32m 154\u001b[0m sources[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mellipticity\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1.0\u001b[39m \u001b[38;5;241m-\u001b[39m sources[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m]\u001b[38;5;241m.\u001b[39mvalues \u001b[38;5;241m/\u001b[39m a\n\u001b[1;32m 156\u001b[0m \u001b[38;5;66;03m# ── Negative pixel extent in aperture ────────────────────────────\u001b[39;00m\n\u001b[1;32m 157\u001b[0m \u001b[38;5;66;03m# Real point sources sit on a positive pedestal; noise spikes from\u001b[39;00m\n\u001b[1;32m 158\u001b[0m \u001b[38;5;66;03m# Mexican-hat ringing have a strong negative bowl around the peak.\u001b[39;00m\n\u001b[1;32m 159\u001b[0m \u001b[38;5;66;03m# neg_extent = abs(most-negative pixel in r=2 px aperture), floored\u001b[39;00m\n\u001b[1;32m 160\u001b[0m \u001b[38;5;66;03m# at zero. Small background fluctuations (±few counts) are ignored;\u001b[39;00m\n\u001b[1;32m 161\u001b[0m \u001b[38;5;66;03m# only swings of tens or hundreds of counts flag a detection as noise.\u001b[39;00m\n\u001b[0;32m--> 162\u001b[0m sources[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mneg_extent\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_neg_pixel_extent\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdata_sub\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msources\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mr\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m2.0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 164\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mbackground_ \u001b[38;5;241m=\u001b[39m bkg\n\u001b[1;32m 165\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m sources\n", - "Cell \u001b[0;32mIn[201], line 206\u001b[0m, in \u001b[0;36mTESSSourceFinder._neg_pixel_extent\u001b[0;34m(data_sub, sources, r)\u001b[0m\n\u001b[1;32m 204\u001b[0m extents[i] \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mnan\n\u001b[1;32m 205\u001b[0m \u001b[38;5;28;01mcontinue\u001b[39;00m\n\u001b[0;32m--> 206\u001b[0m extents[i] \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnanmax\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m0.0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[38;5;28;43mfloat\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mdata_sub\u001b[49m\u001b[43m[\u001b[49m\u001b[43mpy\u001b[49m\u001b[43m[\u001b[49m\u001b[43mvalid\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpx\u001b[49m\u001b[43m[\u001b[49m\u001b[43mvalid\u001b[49m\u001b[43m]\u001b[49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmin\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;241m/\u001b[39m data_sub[ys,xs]\n\u001b[1;32m 208\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m extents\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/numpy/lib/nanfunctions.py:483\u001b[0m, in \u001b[0;36mnanmax\u001b[0;34m(a, axis, out, keepdims, initial, where)\u001b[0m\n\u001b[1;32m 480\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 481\u001b[0m \u001b[38;5;66;03m# Slow, but safe for subclasses of ndarray\u001b[39;00m\n\u001b[1;32m 482\u001b[0m a, mask \u001b[38;5;241m=\u001b[39m _replace_nan(a, \u001b[38;5;241m-\u001b[39mnp\u001b[38;5;241m.\u001b[39minf)\n\u001b[0;32m--> 483\u001b[0m res \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mamax\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxis\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mout\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 484\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m mask \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 485\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m res\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/numpy/core/fromnumeric.py:2827\u001b[0m, in \u001b[0;36mamax\u001b[0;34m(a, axis, out, keepdims, initial, where)\u001b[0m\n\u001b[1;32m 2814\u001b[0m \u001b[38;5;129m@array_function_dispatch\u001b[39m(_max_dispatcher)\n\u001b[1;32m 2815\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mamax\u001b[39m(a, axis\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, out\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, keepdims\u001b[38;5;241m=\u001b[39mnp\u001b[38;5;241m.\u001b[39m_NoValue, initial\u001b[38;5;241m=\u001b[39mnp\u001b[38;5;241m.\u001b[39m_NoValue,\n\u001b[1;32m 2816\u001b[0m where\u001b[38;5;241m=\u001b[39mnp\u001b[38;5;241m.\u001b[39m_NoValue):\n\u001b[1;32m 2817\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 2818\u001b[0m \u001b[38;5;124;03m Return the maximum of an array or maximum along an axis.\u001b[39;00m\n\u001b[1;32m 2819\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 2825\u001b[0m \u001b[38;5;124;03m ndarray.max : equivalent method\u001b[39;00m\n\u001b[1;32m 2826\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m-> 2827\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_wrapreduction\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmaximum\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mmax\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2828\u001b[0m \u001b[43m \u001b[49m\u001b[43mkeepdims\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mkeepdims\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minitial\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minitial\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mwhere\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mwhere\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/numpy/core/fromnumeric.py:88\u001b[0m, in \u001b[0;36m_wrapreduction\u001b[0;34m(obj, ufunc, method, axis, dtype, out, **kwargs)\u001b[0m\n\u001b[1;32m 85\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 86\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m reduction(axis\u001b[38;5;241m=\u001b[39maxis, out\u001b[38;5;241m=\u001b[39mout, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mpasskwargs)\n\u001b[0;32m---> 88\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mufunc\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mreduce\u001b[49m\u001b[43m(\u001b[49m\u001b[43mobj\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxis\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mout\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mpasskwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[0;31mTypeError\u001b[0m: 'float' object cannot be interpreted as an integer" - ] - } - ], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 183, - "id": "9abfbc6e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loading data...\n", - "Running base spatial grouping...\n", - "Scanning for the most linear, highly-spread actual objects...\n", - "Top 4 moving candidates in real data:\n", - " obj size max_std max_corr score\n", - "2 5 73 4.006125 0.651297 2.609179\n", - "3 9 31 2.591259 0.734998 1.904571\n", - "1 4 121 6.757427 0.264839 1.789630\n", - "11 29 24 1.528329 0.910105 1.390940\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Saved real_asteroid_candidates.png\n" - ] - } - ], - "source": [ - "import pandas as pd\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import sys\n", - "\n", - "print(\"Loading data...\")\n", - "df = good#pd.read_csv('/Users/rri38/Documents/work/code/tess/test_tessellate/detected_sources.csv')\n", - "sys.path.insert(0, '/Users/rri38/Documents/work/code/tess/tessellate')\n", - "from tessellate import detector\n", - "\n", - "# Clean NA\n", - "df_clean = df.copy().drop(columns=['objid', 'objid_old', 'objid_new'], errors='ignore')\n", - "\n", - "# Use standard spatial group but with a generous distance to guarantee any asteroid trails are grouped together\n", - "print(\"Running base spatial grouping...\")\n", - "df_grouped = detector._Spatial_group(df_clean, colname='obj', distance=2.0)\n", - "\n", - "results = []\n", - "print(\"Scanning for the most linear, highly-spread actual objects...\")\n", - "for oid, sub in df_grouped.groupby('obj'):\n", - " if len(sub) > 5:\n", - " std_x = sub['xcentroid'].std()\n", - " std_y = sub['ycentroid'].std()\n", - " std_t = sub['frame'].std()\n", - " \n", - " corr_x_t = abs(sub['xcentroid'].corr(sub['frame'])) if std_x > 0 and std_t > 0 else 0\n", - " corr_y_t = abs(sub['ycentroid'].corr(sub['frame'])) if std_y > 0 and std_t > 0 else 0\n", - " \n", - " max_std = max(std_x, std_y)\n", - " max_corr = max(corr_x_t, corr_y_t)\n", - " \n", - " results.append({\n", - " 'obj': oid,\n", - " 'size': len(sub),\n", - " 'max_std': max_std,\n", - " 'max_corr': max_corr,\n", - " 'corr_x': corr_x_t,\n", - " 'corr_y': corr_y_t,\n", - " 'std_x': std_x,\n", - " 'std_y': std_y\n", - " })\n", - "\n", - "df_res = pd.DataFrame(results)\n", - "\n", - "# Sort by those that have both highest spatial spread AND highest correlation\n", - "# Let's define a score: max_std * max_corr\n", - "df_res['score'] = df_res['max_std'] * df_res['max_corr']\n", - "top_candidates = df_res.sort_values(by='score', ascending=False).head(4)\n", - "\n", - "print(f\"Top 4 moving candidates in real data:\")\n", - "print(top_candidates[['obj', 'size', 'max_std', 'max_corr', 'score']])\n", - "\n", - "actual_top_ids = top_candidates['obj'].tolist()\n", - "\n", - "fig, axes = plt.subplots(1, len(actual_top_ids), figsize=(16, 5))\n", - "if len(actual_top_ids) == 1:\n", - " axes = [axes]\n", - "\n", - "for i, oid in enumerate(actual_top_ids):\n", - " ax = axes[i]\n", - " sub = df_grouped[df_grouped['obj'] == oid]\n", - " \n", - " # Plot background\n", - " bg_mask = (df_grouped['xcentroid'] > sub['xcentroid'].min() - 3) & \\\n", - " (df_grouped['xcentroid'] < sub['xcentroid'].max() + 3) & \\\n", - " (df_grouped['ycentroid'] > sub['ycentroid'].min() - 3) & \\\n", - " (df_grouped['ycentroid'] < sub['ycentroid'].max() + 3) & \\\n", - " (df_grouped['obj'] != oid)\n", - " \n", - " ax.scatter(df_grouped[bg_mask]['xcentroid'], df_grouped[bg_mask]['ycentroid'], color='grey', s=5, alpha=0.3, label='Static Sources')\n", - " \n", - " # Plot candidate\n", - " # Color by frame to show progression over time!\n", - " sc = ax.scatter(sub['xcentroid'], sub['ycentroid'], c=sub['frame'], cmap='plasma', s=40, label=f'Obj {oid}')\n", - " cb = plt.colorbar(sc, ax=ax)\n", - " cb.set_label('Frame')\n", - " \n", - " # Check linear fit\n", - " if len(sub) > 2:\n", - " vx, x0 = np.polyfit(sub['frame'], sub['xcentroid'], 1)\n", - " vy, y0 = np.polyfit(sub['frame'], sub['ycentroid'], 1)\n", - " f_min, f_max = sub['frame'].min(), sub['frame'].max()\n", - " x_min, x_max = vx*f_min+x0, vx*f_max+x0\n", - " y_min, y_max = vy*f_min+y0, vy*f_max+y0\n", - " ax.plot([x_min, x_max], [y_min, y_max], color='red', linestyle='--', label='Linear Trajectory')\n", - " \n", - " cand_info = top_candidates[top_candidates['obj'] == oid].iloc[0]\n", - " ax.set_title(f\"Obj {oid} | Std: {cand_info['max_std']:.2f} | Corr: {cand_info['max_corr']:.2f}\")\n", - " ax.legend(loc='lower left', prop={'size': 8})\n", - "\n", - "plt.tight_layout()\n", - "#plt.savefig('/Users/rri38/Documents/work/code/tess/test_tessellate/real_asteroid_candidates.png', dpi=300)\n", - "print(\"Saved real_asteroid_candidates.png\")\n" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "20f8c55a", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.lc[1])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "052bb1a1", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.2" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/development/temporal_smoothing_background_tessellate_example.ipynb b/development/temporal_smoothing_background_tessellate_example.ipynb deleted file mode 100644 index f462a20..0000000 --- a/development/temporal_smoothing_background_tessellate_example.ipynb +++ /dev/null @@ -1,22760 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "2c503328", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import tessreduce as tr\n", - "%matplotlib notebook" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "94e9bf27", - "metadata": {}, - "outputs": [], - "source": [ - "flux = np.load('../../test_tessellate/sector38_cam4_ccd1_cut3_of64_ReducedFlux.npy')\n", - "ref = np.load('../../test_tessellate/sector38_cam4_ccd1_cut3_of64_Ref.npy')" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "bd18501c", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(flux[2756],vmax=10,vmin=-10)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "f259fc2b", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(flux[:,143,173])" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "64c1c3ea", - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "made reference\n", - "made source mask\n", - "calculating background\n", - "adaptive bkg\n", - "background subtracted\n", - "aligning images\n", - "[SepAligner] 229 sources selected for alignment\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "images shifted\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess = tr.tessreduce(tpf='/Users/rri38/Documents/work/data/tess/tessellate_test/sector38_cam4_ccd1_cut3_of64_s38.fits',\n", - " calibrate=False,quality_bitmask='hard',reduce=True,diff=False,align=True,\n", - " shift_method='sep_core',diagnostic_plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "cce0f092", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.bkg[:,100,100])" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "eead2116", - "metadata": {}, - "outputs": [], - "source": [ - "tess.tpf.sector" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "7327b37e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "4" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.tpf.cameraera" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3674a0ae", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "40495fe1", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy.ndimage import median_filter\n", - "\n", - "\n", - "def adaptive_medfilt_3d(\n", - " data,\n", - " w_min=3,\n", - " w_max=51,\n", - " grad_smooth_window=11,\n", - " low_pct=5,\n", - " high_pct=95,\n", - " per_pixel_norm=True,\n", - "):\n", - " data = np.asarray(data, dtype=float)\n", - " T, X, Y = data.shape\n", - "\n", - " # NaN fill along time axis\n", - " nan_mask = ~np.isfinite(data)\n", - " data_filled = data.copy()\n", - " if nan_mask.any():\n", - " t_ax = np.arange(T, dtype=float)\n", - " for xi in range(X):\n", - " for yi in range(Y):\n", - " ts = data[:, xi, yi]\n", - " bad = ~np.isfinite(ts)\n", - " if bad.all():\n", - " data_filled[:, xi, yi] = 0.0\n", - " elif bad.any():\n", - " data_filled[:, xi, yi] = np.interp(t_ax, t_ax[~bad], ts[~bad])\n", - "\n", - " # Gradient → smooth → |grad|\n", - " grad = np.gradient(data_filled, axis=0)\n", - " gw = _make_odd(grad_smooth_window)\n", - " abs_grad = np.abs(median_filter(grad, size=(gw, 1, 1), mode='reflect'))\n", - "\n", - " # Map |gradient| → window size\n", - " if per_pixel_norm:\n", - " g_lo = np.nanpercentile(abs_grad, low_pct, axis=0, keepdims=True)\n", - " g_hi = np.nanpercentile(abs_grad, high_pct, axis=0, keepdims=True)\n", - " else:\n", - " g_lo = np.nanpercentile(abs_grad, low_pct)\n", - " g_hi = np.nanpercentile(abs_grad, high_pct)\n", - "\n", - " dg = np.where((g_hi - g_lo) > 0, g_hi - g_lo, 1.0)\n", - " norm = np.clip((abs_grad - g_lo) / dg, 0.0, 1.0)\n", - "\n", - " raw = w_max - norm * (w_max - w_min)\n", - " windows = np.round(raw).astype(int)\n", - " windows += (1 - windows % 2)\n", - " windows = np.clip(windows, _make_odd(w_min), _make_odd(w_max))\n", - "\n", - " # Adaptive median: loop over unique window sizes\n", - " result = np.empty((T, X, Y))\n", - " for w in np.unique(windows):\n", - " smoothed_w = median_filter(data_filled, size=(w, 1, 1), mode='reflect')\n", - " result[windows == w] = smoothed_w[windows == w]\n", - "\n", - " result[nan_mask] = np.nan\n", - " return result, windows, abs_grad\n", - "\n", - "\n", - "def _make_odd(x):\n", - " x = max(int(x), 3)\n", - " return x if x % 2 == 1 else x + 1" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "db6b1d94", - "metadata": {}, - "outputs": [], - "source": [ - "data = tr.deepcopy(tess.bkg)\n", - "w_min=3\n", - "w_max=51\n", - "grad_smooth_window=11\n", - "low_pct=5\n", - "high_pct=95\n", - "per_pixel_norm=True\n", - "\n", - "data = np.asarray(data, dtype=float)\n", - "T, X, Y = data.shape\n", - "\n", - "# NaN fill along time axis\n", - "nan_mask = ~np.isfinite(data)\n", - "data_filled = data.copy()\n", - "if nan_mask.any():\n", - " t_ax = np.arange(T, dtype=float)\n", - " for xi in range(X):\n", - " for yi in range(Y):\n", - " ts = data[:, xi, yi]\n", - " bad = ~np.isfinite(ts)\n", - " if bad.all():\n", - " data_filled[:, xi, yi] = 0.0\n", - " elif bad.any():\n", - " data_filled[:, xi, yi] = np.interp(t_ax, t_ax[~bad], ts[~bad])\n", - "\n", - "# Gradient → smooth → |grad|\n", - "grad = np.gradient(data_filled, axis=0)\n", - "gw = _make_odd(grad_smooth_window)\n", - "abs_grad = np.abs(median_filter(grad, size=(gw, 1, 1), mode='reflect'))\n", - "\n", - "# Map |gradient| → window size\n", - "if per_pixel_norm:\n", - " g_lo = np.nanpercentile(abs_grad, low_pct, axis=0, keepdims=True)\n", - " g_hi = np.nanpercentile(abs_grad, high_pct, axis=0, keepdims=True)\n", - "else:\n", - " g_lo = np.nanpercentile(abs_grad, low_pct)\n", - " g_hi = np.nanpercentile(abs_grad, high_pct)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "e71c2776", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "f3e864d4", - "metadata": {}, - "outputs": [], - "source": [ - "np.save('test_bkg.npy',tess.bkg)\n", - "np.save('test_bkg_time.npy',tess.mjd)" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "b9b534a9", - "metadata": {}, - "outputs": [], - "source": [ - "acc = np.gradient(median_filter(grad, size=(gw, 1, 1), mode='reflect'),axis=0)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "7356e433", - "metadata": {}, - "outputs": [], - "source": [ - "sacc = median_filter(acc, size=(21, 1, 1), mode='reflect')" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "b4f69323", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(abs_grad[:,100,100])\n", - "plt.plot(abs(sacc[:,100,100])*10)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "43ace160", - "metadata": {}, - "outputs": [], - "source": [ - "dg = np.where((g_hi - g_lo) > 0, g_hi - g_lo, 1.0)\n", - "norm = np.clip((abs_grad - g_lo) / dg, 0.0, 1.0)\n", - "\n", - "raw = w_max - norm * (w_max - w_min)\n", - "windows = np.round(raw).astype(int)\n", - "windows += (1 - windows % 2)\n", - "windows = np.clip(windows, _make_odd(w_min), _make_odd(w_max))" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "e142090a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([33, 33, 33, ..., 47, 47, 45])" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "windows[:,100,100]" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "8d0becab", - "metadata": {}, - "outputs": [], - "source": [ - "b = data[:,100,100]\n", - "bs = medfilt(b,11)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "18810a43", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(b)\n", - "plt.plot(bs)\n", - "plt.plot(abs_grad[:,100,100]*100+70)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "526d3e8a", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(abs_grad[:,100,100])" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "69568e5a", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.flux[10]-(tess.ref-tess.bkg[tess.ref_ind]),vmin=-10,vmax=30,origin='lower')" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "135a0352", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.flux[:,143-10,174-10])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fbf304c6", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "# Adaptive median: loop over unique window sizes\n", - "result = np.empty((T, X, Y))\n", - "for w in np.unique(windows):\n", - " smoothed_w = median_filter(data_filled, size=(w, 1, 1), mode='reflect')\n", - " result[windows == w] = smoothed_w[windows == w]\n", - "\n", - "result[nan_mask] = np.nan" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "ec564d4e", - "metadata": {}, - "outputs": [ - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[5], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m sbkg,ws,grad \u001b[38;5;241m=\u001b[39m \u001b[43madaptive_medfilt_3d\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtess\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbkg\u001b[49m\u001b[43m)\u001b[49m\n", - "Cell \u001b[0;32mIn[4], line 86\u001b[0m, in \u001b[0;36madaptive_medfilt_3d\u001b[0;34m(data, w_min, w_max, grad_smooth_window, low_pct, high_pct, per_pixel_norm)\u001b[0m\n\u001b[1;32m 83\u001b[0m unique_wins \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39munique(windows)\n\u001b[1;32m 85\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m w \u001b[38;5;129;01min\u001b[39;00m unique_wins:\n\u001b[0;32m---> 86\u001b[0m smoothed_w \u001b[38;5;241m=\u001b[39m \u001b[43mmedian_filter\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdata_filled\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msize\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mw\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 87\u001b[0m mask \u001b[38;5;241m=\u001b[39m (windows \u001b[38;5;241m==\u001b[39m w)\n\u001b[1;32m 88\u001b[0m result[mask] \u001b[38;5;241m=\u001b[39m smoothed_w[mask]\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/scipy/ndimage/_filters.py:2134\u001b[0m, in \u001b[0;36mmedian_filter\u001b[0;34m(input, size, footprint, output, mode, cval, origin, axes)\u001b[0m\n\u001b[1;32m 2075\u001b[0m \u001b[38;5;129m@_ni_docstrings\u001b[39m\u001b[38;5;241m.\u001b[39mdocfiller\n\u001b[1;32m 2076\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mmedian_filter\u001b[39m(\u001b[38;5;28minput\u001b[39m, size\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, footprint\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, output\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 2077\u001b[0m mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mreflect\u001b[39m\u001b[38;5;124m\"\u001b[39m, cval\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0.0\u001b[39m, origin\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0\u001b[39m, \u001b[38;5;241m*\u001b[39m, axes\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[1;32m 2078\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 2079\u001b[0m \u001b[38;5;124;03m Calculate a multidimensional median filter.\u001b[39;00m\n\u001b[1;32m 2080\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 2132\u001b[0m \u001b[38;5;124;03m >>> plt.show()\u001b[39;00m\n\u001b[1;32m 2133\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m-> 2134\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_rank_filter\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msize\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfootprint\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moutput\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcval\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 2135\u001b[0m \u001b[43m \u001b[49m\u001b[43morigin\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mmedian\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maxes\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43maxes\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/scipy/ndimage/_filters.py:2021\u001b[0m, in \u001b[0;36m_rank_filter\u001b[0;34m(input, rank, size, footprint, output, mode, cval, origin, operation, axes)\u001b[0m\n\u001b[1;32m 2019\u001b[0m np\u001b[38;5;241m.\u001b[39mcopyto(output, x_out, casting\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124munsafe\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 2020\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 2021\u001b[0m \u001b[43m_nd_image\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrank_filter\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrank\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfootprint\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moutput\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcval\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43morigins\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2022\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m temp_needed:\n\u001b[1;32m 2023\u001b[0m temp[\u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;241m.\u001b[39m] \u001b[38;5;241m=\u001b[39m output\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " - ] - } - ], - "source": [ - "sbkg,ws,grad = adaptive_medfilt_3d(tess.bkg)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0ce2c566", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "07c4eeba", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(3693, 256, 256)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.flux.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "9eed5705", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(3693,)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "av_bkg.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "19633081", - "metadata": {}, - "outputs": [], - "source": [ - "av_bkg = np.nanmedian(tess.flux,axis=(1,2))" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "876ffa20", - "metadata": {}, - "outputs": [], - "source": [ - "from scipy.signal import medfilt" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "e948bfeb", - "metadata": {}, - "outputs": [], - "source": [ - "g = (np.gradient(tess.bkg[:,100,100]))\n", - "gs = medfilt(g,kernel_size=7)\n", - "b = tess.bkg[:,100,100]\n", - "bs = medfilt(tess.bkg,kernel_size=(11,3,3))" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "2219510e", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(b)\n", - "plt.plot(bs[:,100,100])" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "bf96c61c", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(g)\n", - "plt.plot(gs)" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "b5258128", - "metadata": {}, - "outputs": [], - "source": [ - "import sep\n", - "import pandas as pd" - ] - }, - { - "cell_type": "code", - "execution_count": 183, - "id": "d278d1c7", - "metadata": {}, - "outputs": [], - "source": [ - "data = tess.ref.byteswap().newbyteorder()\n", - "# data = tess.flux[100].byteswap().newbyteorder()\n", - "#edata = tess.eflux[tess.ref_ind].byteswap().newbyteorder()\n", - "bkg = sep.Background(data)\n", - "objects = sep.extract(data- np.nanmedian(data), 50,)" - ] - }, - { - "cell_type": "code", - "execution_count": 179, - "id": "83e7e1eb", - "metadata": {}, - "outputs": [], - "source": [ - "objects = pd.DataFrame(objects)\n", - "w = objects['a'].values\n", - "h = objects['b'].values\n", - "ratio = np.round(abs(w/h - 1),1)\n", - "objects = objects.iloc[ratio < 0.5]" - ] - }, - { - "cell_type": "code", - "execution_count": 184, - "id": "cd69ef9a", - "metadata": {}, - "outputs": [], - "source": [ - "np.save('testref.npy',data)" - ] - }, - { - "cell_type": "code", - "execution_count": 180, - "id": "93590baf", - "metadata": {}, - "outputs": [], - "source": [ - "objects.to_csv('test100.csv',index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 181, - "id": "046668d2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1438" - ] - }, - "execution_count": 181, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.ref_ind" - ] - }, - { - "cell_type": "code", - "execution_count": 159, - "id": "4a1ed422", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Index(['thresh', 'npix', 'tnpix', 'xmin', 'xmax', 'ymin', 'ymax', 'x', 'y',\n", - " 'x2', 'y2', 'xy', 'errx2', 'erry2', 'errxy', 'a', 'b', 'theta', 'cxx',\n", - " 'cyy', 'cxy', 'cflux', 'flux', 'cpeak', 'peak', 'xcpeak', 'ycpeak',\n", - " 'xpeak', 'ypeak', 'flag'],\n", - " dtype='object')" - ] - }, - "execution_count": 159, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "objects.keys()" - ] - }, - { - "cell_type": "code", - "execution_count": 155, - "id": "3664c318", - "metadata": {}, - "outputs": [], - "source": [ - "ind = ratio < 0.5" - ] - }, - { - "cell_type": "code", - "execution_count": 161, - "id": "8a4087bc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
xx2
0168.7914360.683582
1176.8900290.966993
280.9229550.564643
3131.9224780.502342
46.2602600.429477
.........
249237.9569580.359582
2509.9094381.230163
25174.5846341.445189
252168.0056841.265719
253202.9302050.520540
\n", - "

254 rows × 2 columns

\n", - "
" - ], - "text/plain": [ - " x x2\n", - "0 168.791436 0.683582\n", - "1 176.890029 0.966993\n", - "2 80.922955 0.564643\n", - "3 131.922478 0.502342\n", - "4 6.260260 0.429477\n", - ".. ... ...\n", - "249 237.956958 0.359582\n", - "250 9.909438 1.230163\n", - "251 74.584634 1.445189\n", - "252 168.005684 1.265719\n", - "253 202.930205 0.520540\n", - "\n", - "[254 rows x 2 columns]" - ] - }, - "execution_count": 161, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "objects[['x','x2']]" - ] - }, - { - "cell_type": "code", - "execution_count": 157, - "id": "0bfac89d", - "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_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 157, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.ref,vmax=1200)\n", - "plt.plot(objects['x'],objects['y'],'C2.')\n", - "plt.plot(objects['x'][ind],objects['y'][ind],'C1.')" - ] - }, - { - "cell_type": "code", - "execution_count": 88, - "id": "891bdd8c", - "metadata": {}, - "outputs": [], - "source": [ - "def bkg_temporal_smooth(self,window_size=None):\n", - " if window_size is None:\n", - " window_size = self._bkg_temporal_window # still need to decide what this is \n", - " \n", - " grad = np.gradient(self.bkg[:,25,25],lc[0])\n", - " time = self.mjd\n", - " m,med,std = sigma_clipped_stats(abs(grad))\n", - " ind = abs(grad) < (med + 5*std)\n", - " ind_where = np.where(ind)[0]\n", - "\n", - " breaks = np.where(np.diff(time[ind]) > 1)[0]+1\n", - " breaks = np.insert(breaks, 0, 0)\n", - " breaks = np.append(breaks, len(time[ind]))\n", - "\n", - " new_bkg = self.bkg.copy() # shape (T, X, Y)\n", - "\n", - " for i in range(len(breaks) - 1):\n", - " seg_idx = ind_where[breaks[i]:breaks[i+1]]\n", - " seg = new_bkg[seg_idx] # (n_seg, X, Y)\n", - " sav = savgol_filter(seg, 501, 1, axis=0) # (n_seg, X, Y)\n", - "\n", - " # per-pixel residual threshold\n", - " resid = np.abs(seg - sav) # (n_seg, X, Y)\n", - " threshold = np.median(resid, axis=0) + 5 * np.std(resid, axis=0) # (X, Y)\n", - "\n", - " exceeds = resid > threshold[np.newaxis] # (n_seg, X, Y)\n", - "\n", - " # leading bad run: cumprod stays 1 only while all preceding values were True\n", - " start_clip = np.cumprod(exceeds,axis=0).sum(axis=0) # (X, Y)\n", - " end_clip = len(seg_idx) - np.cumprod(exceeds[::-1], axis=0).sum(axis=0)\n", - "\n", - " # use sav only within [start_clip, end_clip), raw outside\n", - " t = np.arange(len(seg_idx))[:, np.newaxis, np.newaxis] # (n_seg, 1, 1)\n", - " use_sav = (t >= start_clip) & (t < end_clip)\n", - "\n", - " new_bkg[seg_idx] = np.where(use_sav, sav, seg)\n", - "\n", - "# flux = deepcopy(self.flux)\n", - "# flux += self.bkg - new_bkg\n", - " med = sigma_clipped_stats(flux,axis=(1,2))[1]\n", - " flux = flux - med[:,np.newaxis,np.newaxis]\n", - " new_bkg += med[:,np.newaxis,np.newaxis]\n", - " self.bkg = new_bkg\n", - " self.flux = flux\n" - ] - }, - { - "cell_type": "code", - "execution_count": 214, - "id": "54509c5b", - "metadata": {}, - "outputs": [], - "source": [ - "ind = abs(grad) < (med + 5*std)\n", - "ind_where = np.where(ind)[0]\n", - "\n", - "breaks = np.where(np.diff(time[ind]) > 1)[0]+1\n", - "breaks = np.insert(breaks, 0, 0)\n", - "breaks = np.append(breaks, len(time[ind]))\n", - "\n", - "new_bkg = tess.bkg.copy() # shape (T, X, Y)\n", - "\n", - "for i in range(len(breaks) - 1):\n", - " seg_idx = ind_where[breaks[i]:breaks[i+1]]\n", - " seg = new_bkg[seg_idx] # (n_seg, X, Y)\n", - " sav = savgol_filter(seg, 501, 1, axis=0) # (n_seg, X, Y)\n", - "\n", - " # per-pixel residual threshold\n", - " resid = np.abs(seg - sav) # (n_seg, X, Y)\n", - " threshold = np.median(resid, axis=0) + 5 * np.std(resid, axis=0) # (X, Y)\n", - "\n", - " exceeds = resid > threshold[np.newaxis] # (n_seg, X, Y)\n", - "\n", - " # leading bad run: cumprod stays 1 only while all preceding values were True\n", - " start_clip = np.cumprod(exceeds, axis=0).sum(axis=0) # (X, Y)\n", - " end_clip = len(seg_idx) - np.cumprod(exceeds[::-1], axis=0).sum(axis=0)\n", - "\n", - " # use sav only within [start_clip, end_clip), raw outside\n", - " t = np.arange(len(seg_idx))[:, np.newaxis, np.newaxis] # (n_seg, 1, 1)\n", - " use_sav = (t >= start_clip) & (t < end_clip)\n", - "\n", - " new_bkg[seg_idx] = np.where(use_sav, sav, seg)\n", - "\n", - "flux = deepcopy(tess.flux)\n", - "flux += tess.bkg - new_bkg\n", - "med = sigma_clipped_stats(flux,axis=(1,2))[1]\n", - "flux = flux - med[:,np.newaxis,np.newaxis]\n", - "new_bkg += med[:,np.newaxis,np.newaxis]\n" - ] - }, - { - "cell_type": "code", - "execution_count": 218, - "id": "d34782f3", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 218, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(np.nansum(tess.flux[:,24:27,24:27],axis=(1,2)),label='old')\n", - "plt.plot(np.nansum(flux[:,24:27,24:27],axis=(1,2)),label='new')\n", - "#plt.plot(np.nansum(aflux[:,24:27,24:27],axis=(1,2)),label='new')\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 190, - "id": "2b1a3725", - "metadata": {}, - "outputs": [], - "source": [ - "np.save('flux_test.npy',tess.flux)" - ] - }, - { - "cell_type": "code", - "execution_count": 219, - "id": "2c40949e", - "metadata": {}, - "outputs": [], - "source": [ - "lc1 = np.nansum(tess.flux[:,24:27,24:27],axis=(1,2))\n", - "lc2 = np.nansum(flux[:,24:27,24:27],axis=(1,2))" - ] - }, - { - "cell_type": "code", - "execution_count": 224, - "id": "0dae5c1f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "27.354153455917178" - ] - }, - "execution_count": 224, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sigma_clipped_stats(lc1)[2] * 3" - ] - }, - { - "cell_type": "code", - "execution_count": 225, - "id": "9a6d9d96", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "15.741954697000537" - ] - }, - "execution_count": 225, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sigma_clipped_stats(lc2)[2] *3" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "05f9a847", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 222, - "id": "efa28f19", - "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_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 222, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "j = 1835#2855\n", - "plt.figure()\n", - "plt.subplot(121)\n", - "plt.imshow(tess.flux[j],vmin=-10,vmax=10)\n", - "\n", - "plt.subplot(122)\n", - "plt.imshow(flux[j],vmin=-10,vmax=10)" - ] - }, - { - "cell_type": "code", - "execution_count": 151, - "id": "b0ab1e2a", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 159, - "id": "f3a61814", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([ 0.13595049, 0.21746506, 0.10541646, ..., -0.1851571 ,\n", - " 0.30301034, 0.19434366])" - ] - }, - "execution_count": 159, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a[1]" - ] - }, - { - "cell_type": "code", - "execution_count": 147, - "id": "98a892c5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.28194623356385085, 0.2497329419029134, 1.2707684836536026)" - ] - }, - "execution_count": 147, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sigma_clipped_stats(tess.flux[j] + tess.bkg[j] - new_bkg[j])" - ] - }, - { - "cell_type": "code", - "execution_count": 163, - "id": "dde742d4", - "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_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "ind = abs(grad) < (med + 5*std)\n", - "ind_where = np.where(ind)[0]\n", - "\n", - "breaks = np.where(np.diff(time[ind]) > 1)[0]+1\n", - "breaks = np.insert(breaks, 0, 0)\n", - "breaks = np.append(breaks, len(time[ind]))\n", - "\n", - "new_bkg = deepcopy(tess.bkg[:,25,25])\n", - "\n", - "for i in range(len(breaks) - 1):\n", - " seg_idx = ind_where[breaks[i]:breaks[i+1]]\n", - " seg = new_bkg[seg_idx]\n", - " sav = savgol_filter(seg, 51, 3)\n", - "\n", - " # find poorly-fit edge points and revert to original\n", - " resid = np.abs(seg - sav)\n", - " threshold = np.median(resid) + 5 * np.std(resid)\n", - "\n", - " # clip start: walk inward until residual is acceptable\n", - " start_clip = 0\n", - " for j in range(len(sav)):\n", - " if resid[j] > threshold:\n", - " start_clip = j + 1\n", - " else:\n", - " break\n", - "\n", - " # clip end: walk inward from the right\n", - " end_clip = len(sav)\n", - " for j in range(len(sav) - 1, -1, -1):\n", - " if resid[j] > threshold:\n", - " end_clip = j\n", - " else:\n", - " break\n", - "\n", - " sav[:start_clip] = seg[:start_clip]\n", - " sav[end_clip:] = seg[end_clip:]\n", - "\n", - "# plt.figure()\n", - "# plt.plot(seg, '.')\n", - "# plt.plot(sav)\n", - " new_bkg[seg_idx] = sav\n", - " \n", - "flux = deepcopy(tess.flux)\n", - "flux += tess.bkg - new_bkg\n", - "med = sigma_clipped_stats(flux,axis=(1,2))[1]\n", - "flux = flux - med\n", - " \n", - " \n", - "# plt.figure()\n", - "# plt.plot(tess.bkg[ind,25,25],'.')\n", - "# plt.plot(new_bkg[ind])\n", - "\n", - "# plt.figure()\n", - "# plt.plot(tess.bkg[:,25,25]-new_bkg,'.')\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 161, - "id": "db081ce9", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(3471,)" - ] - }, - "execution_count": 161, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "new_bkg.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 167, - "id": "14839742", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "ename": "ValueError", - "evalue": "x and y can be no greater than 2D, but have shapes (3471,) and (3471, 50, 50)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[167], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m plt\u001b[38;5;241m.\u001b[39mfigure()\n\u001b[0;32m----> 2\u001b[0m \u001b[43mplt\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mplot\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnew_bkg\u001b[49m\u001b[43m,\u001b[49m\u001b[43mlabel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mbkg\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 3\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(tess\u001b[38;5;241m.\u001b[39mflux[:,\u001b[38;5;241m25\u001b[39m,\u001b[38;5;241m25\u001b[39m],\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m'\u001b[39m,label\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlc\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 4\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(tess\u001b[38;5;241m.\u001b[39mflux[:,\u001b[38;5;241m25\u001b[39m,\u001b[38;5;241m25\u001b[39m] \u001b[38;5;241m+\u001b[39m tess\u001b[38;5;241m.\u001b[39mbkg[:,\u001b[38;5;241m25\u001b[39m,\u001b[38;5;241m25\u001b[39m] \u001b[38;5;241m-\u001b[39m new_bkg,\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m'\u001b[39m,label\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlc\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/matplotlib/pyplot.py:3838\u001b[0m, in \u001b[0;36mplot\u001b[0;34m(scalex, scaley, data, *args, **kwargs)\u001b[0m\n\u001b[1;32m 3830\u001b[0m \u001b[38;5;129m@_copy_docstring_and_deprecators\u001b[39m(Axes\u001b[38;5;241m.\u001b[39mplot)\n\u001b[1;32m 3831\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mplot\u001b[39m(\n\u001b[1;32m 3832\u001b[0m \u001b[38;5;241m*\u001b[39margs: \u001b[38;5;28mfloat\u001b[39m \u001b[38;5;241m|\u001b[39m ArrayLike \u001b[38;5;241m|\u001b[39m \u001b[38;5;28mstr\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 3836\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs,\n\u001b[1;32m 3837\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28mlist\u001b[39m[Line2D]:\n\u001b[0;32m-> 3838\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mgca\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mplot\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 3839\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3840\u001b[0m \u001b[43m \u001b[49m\u001b[43mscalex\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mscalex\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3841\u001b[0m \u001b[43m \u001b[49m\u001b[43mscaley\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mscaley\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3842\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m{\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mdata\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m}\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mis\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3843\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3844\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/matplotlib/axes/_axes.py:1777\u001b[0m, in \u001b[0;36mAxes.plot\u001b[0;34m(self, scalex, scaley, data, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1534\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 1535\u001b[0m \u001b[38;5;124;03mPlot y versus x as lines and/or markers.\u001b[39;00m\n\u001b[1;32m 1536\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1774\u001b[0m \u001b[38;5;124;03m(``'green'``) or hex strings (``'#008000'``).\u001b[39;00m\n\u001b[1;32m 1775\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 1776\u001b[0m kwargs \u001b[38;5;241m=\u001b[39m cbook\u001b[38;5;241m.\u001b[39mnormalize_kwargs(kwargs, mlines\u001b[38;5;241m.\u001b[39mLine2D)\n\u001b[0;32m-> 1777\u001b[0m lines \u001b[38;5;241m=\u001b[39m [\u001b[38;5;241m*\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_lines(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m*\u001b[39margs, data\u001b[38;5;241m=\u001b[39mdata, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)]\n\u001b[1;32m 1778\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m line \u001b[38;5;129;01min\u001b[39;00m lines:\n\u001b[1;32m 1779\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39madd_line(line)\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/matplotlib/axes/_base.py:297\u001b[0m, in \u001b[0;36m_process_plot_var_args.__call__\u001b[0;34m(self, axes, data, return_kwargs, *args, **kwargs)\u001b[0m\n\u001b[1;32m 295\u001b[0m this \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m args[\u001b[38;5;241m0\u001b[39m],\n\u001b[1;32m 296\u001b[0m args \u001b[38;5;241m=\u001b[39m args[\u001b[38;5;241m1\u001b[39m:]\n\u001b[0;32m--> 297\u001b[0m \u001b[38;5;28;01myield from\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_plot_args\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 298\u001b[0m \u001b[43m \u001b[49m\u001b[43maxes\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mthis\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mambiguous_fmt_datakey\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mambiguous_fmt_datakey\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 299\u001b[0m \u001b[43m \u001b[49m\u001b[43mreturn_kwargs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mreturn_kwargs\u001b[49m\n\u001b[1;32m 300\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/matplotlib/axes/_base.py:497\u001b[0m, in \u001b[0;36m_process_plot_var_args._plot_args\u001b[0;34m(self, axes, tup, kwargs, return_kwargs, ambiguous_fmt_datakey)\u001b[0m\n\u001b[1;32m 494\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mx and y must have same first dimension, but \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 495\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhave shapes \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mx\u001b[38;5;241m.\u001b[39mshape\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m and \u001b[39m\u001b[38;5;132;01m{\u001b[39;00my\u001b[38;5;241m.\u001b[39mshape\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 496\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m x\u001b[38;5;241m.\u001b[39mndim \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m2\u001b[39m \u001b[38;5;129;01mor\u001b[39;00m y\u001b[38;5;241m.\u001b[39mndim \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m2\u001b[39m:\n\u001b[0;32m--> 497\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mx and y can be no greater than 2D, but have \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 498\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mshapes \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mx\u001b[38;5;241m.\u001b[39mshape\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m and \u001b[39m\u001b[38;5;132;01m{\u001b[39;00my\u001b[38;5;241m.\u001b[39mshape\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 499\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m x\u001b[38;5;241m.\u001b[39mndim \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m 500\u001b[0m x \u001b[38;5;241m=\u001b[39m x[:, np\u001b[38;5;241m.\u001b[39mnewaxis]\n", - "\u001b[0;31mValueError\u001b[0m: x and y can be no greater than 2D, but have shapes (3471,) and (3471, 50, 50)" - ] - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(new_bkg,label='bkg')\n", - "plt.plot(tess.flux[:,25,25],'.',label='lc')\n", - "plt.plot(tess.flux[:,25,25] + tess.bkg[:,25,25] - new_bkg,'.',label='lc')\n", - "plt.legend()\n", - "plt.ylim(-4,20)" - ] - }, - { - "cell_type": "code", - "execution_count": 126, - "id": "87a633a7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.1992238794252621, 0.14485954705463833, 1.2108414313258078)" - ] - }, - "execution_count": 126, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sigma_clipped_stats(tess.flux[:,25,25])" - ] - }, - { - "cell_type": "code", - "execution_count": 125, - "id": "ec81dea2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(0.18983479459023306, 0.13764954448826572, 0.9358091876427621)" - ] - }, - "execution_count": 125, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sigma_clipped_stats(tess.flux[:,25,25] + tess.bkg[:,25,25] - new_bkg)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "01f5e768", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from scipy.ndimage import gaussian_filter1d\n", - "\n", - "def adaptive_gaussian_smooth(time, bkg, sigma_min_hrs=0.5, sigma_max_hrs=6,\n", - " n_levels=15, gap_threshold_hrs=1.0,\n", - " raw_grad_threshold=0.3, spike_nsigma=5):\n", - " '''\n", - " Adaptive Gaussian smoothing in physical time units, respecting data gaps.\n", - "\n", - " Points are left as raw data if they have a high local gradient OR are\n", - " significantly elevated above the local baseline (catches full spike decay).\n", - "\n", - " Parameters\n", - " ----------\n", - " time : 1D array of times (days)\n", - " bkg : 1D array of background values\n", - " sigma_min_hrs : minimum smoothing width in hours (near rapid changes)\n", - " sigma_max_hrs : maximum smoothing width in hours (steady regions)\n", - " n_levels : number of pre-computed sigma levels\n", - " gap_threshold_hrs : gaps larger than this split data into independent segments\n", - " raw_grad_threshold : gradient fraction [0-1] above which points are left raw\n", - " spike_nsigma : points more than this many sigma above local baseline\n", - " are also left raw\n", - " '''\n", - " dt_hrs = np.median(np.diff(time)) * 24\n", - " sigma_min = sigma_min_hrs / dt_hrs\n", - " sigma_max = sigma_max_hrs / dt_hrs\n", - "\n", - " gaps = np.diff(time) * 24\n", - " seg_breaks = np.where(gaps > gap_threshold_hrs)[0] + 1\n", - " seg_starts = np.concatenate([[0], seg_breaks])\n", - " seg_ends = np.concatenate([seg_breaks, [len(bkg)]])\n", - "\n", - " result = bkg.copy()\n", - "\n", - " for s, e in zip(seg_starts, seg_ends):\n", - " seg = bkg[s:e]\n", - " sigmas = np.geomspace(sigma_min, sigma_max, n_levels)\n", - "\n", - " # Robust baseline and noise estimate from the lower 60th percentile\n", - " lo = seg <= np.percentile(seg, 60)\n", - " baseline = np.median(seg[lo])\n", - " noise = np.median(np.abs(seg[lo] - baseline))\n", - " noise = max(noise, 1e-6)\n", - "\n", - " # Gradient-based raw mask\n", - " grad = np.abs(np.gradient(seg))\n", - " p_hi = np.percentile(grad, 99)\n", - " grad_norm = np.clip(grad / (p_hi + 1e-10), 0, 1)\n", - "\n", - " # Combined raw mask: high gradient OR elevated above baseline\n", - " raw_mask = (grad_norm >= raw_grad_threshold) | (seg > baseline + spike_nsigma * noise)\n", - " smooth_mask = ~raw_mask\n", - "\n", - " # Sigma index: high gradient -> sigma_min, flat -> sigma_max\n", - " sigma_idx = (1.0 - grad_norm ** 2) * (n_levels - 1)\n", - " sigma_idx = gaussian_filter1d(sigma_idx, sigma=max(1, 1.0 / dt_hrs))\n", - " sigma_idx = np.clip(sigma_idx, 0, n_levels - 1)\n", - "\n", - " # Pre-compute smoothed versions at each sigma level\n", - " smoothed = np.array([gaussian_filter1d(seg, sigma=sig, mode='nearest')\n", - " for sig in sigmas])\n", - "\n", - " # Interpolate between adjacent levels\n", - " idx_lo = np.clip(sigma_idx.astype(int), 0, n_levels - 2)\n", - " idx_hi = idx_lo + 1\n", - " frac = sigma_idx - idx_lo\n", - " val_lo = np.take_along_axis(smoothed, idx_lo[np.newaxis], axis=0)[0]\n", - " val_hi = np.take_along_axis(smoothed, idx_hi[np.newaxis], axis=0)[0]\n", - " blended = (1.0 - frac) * val_lo + frac * val_hi\n", - "\n", - " seg_result = seg.copy()\n", - " seg_result[smooth_mask] = blended[smooth_mask]\n", - " result[s:e] = seg_result\n", - "\n", - " return result" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "391b1c86", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2eb40bd7", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "07c3eed9", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "819f5c28", - "metadata": {}, - "outputs": [], - "source": [ - "lc = np.array([tess.tpf.time.mjd,tess.bkg[:,25,25]])" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "0b03279d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(2, 3471)" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "lc.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "fdaf4f78", - "metadata": {}, - "outputs": [], - "source": [ - "np.save('test_bkg.npy',lc)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "b80b7821", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "/Users/rri38/Documents/work/code/tess/tessreduce/development\r\n" - ] - } - ], - "source": [ - "!pwd" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "ca33b668", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.bkg[1000])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "28cab8eb", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.2" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/development/tess_utils.ipynb b/development/tess_utils.ipynb index b909f5d..8b0a7e9 100755 --- a/development/tess_utils.ipynb +++ b/development/tess_utils.ipynb @@ -4083,7 +4083,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -4097,7 +4097,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.2" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/development/test100.csv b/development/test100.csv deleted file mode 100644 index 69a2bf9..0000000 --- a/development/test100.csv +++ /dev/null @@ -1,278 +0,0 @@ -thresh,npix,tnpix,xmin,xmax,ymin,ymax,x,y,x2,y2,xy,errx2,erry2,errxy,a,b,theta,cxx,cyy,cxy,cflux,flux,cpeak,peak,xcpeak,ycpeak,xpeak,ypeak,flag -50.0,8,5,139,142,0,2,140.47367106212212,0.9858518614151516,0.6953136239682607,0.44375819044195064,-0.0029959250264484094,0.0,0.0,0.0,0.8338760733604431,0.6661249995231628,-0.011907350271940231,1.438241720199585,2.253545045852661,0.019419874995946884,511.9964904785156,644.0380859375,86.04055786132812,154.9273681640625,140,1,141,1,2 -50.0,16,9,130,134,0,3,131.96383177887705,1.4910451919120955,0.8791781812470942,0.7772837358358191,0.010973982757600087,0.0,0.0,0.0,0.9382678866386414,0.8809740543365479,0.10607876628637314,1.13762629032135,1.286758303642273,-0.03212286904454231,2536.822509765625,2716.2705078125,357.420654296875,665.874755859375,132,1,132,2,2 -50.0,13,8,167,170,0,3,168.69910993475733,1.0649000044596435,0.796468778067652,0.6409311963679445,0.03683535395875026,0.0,0.0,0.0,0.8970792889595032,0.7953921556472778,0.22117401659488678,1.2588881254196167,1.5643879175186157,-0.14470067620277405,2499.0830078125,2801.828125,417.1434631347656,869.2147216796875,169,1,169,1,2 -50.0,18,11,175,179,0,3,176.9189060211316,0.9350555927454673,0.9983119439723538,0.666948296674641,0.007458178484819333,0.0,0.0,0.0,0.9992395639419556,0.8165662884712219,0.02249234914779663,1.001774549484253,1.4994919300079346,-0.022404776886105537,6592.05322265625,7299.130859375,1046.9161376953125,2148.44384765625,177,1,177,1,2 -50.0,13,9,79,82,1,4,80.84895628333071,2.509619575640375,0.6638897340199228,0.8418287000329352,-0.036493771252761764,0.0,0.0,0.0,0.921424150466919,0.8103678226470947,-1.3761693239212036,1.5098721981048584,1.1907275915145874,0.13090769946575165,1520.6046142578125,1704.3441162109375,220.3207244873047,398.96319580078125,81,2,81,2,0 -50.0,41,30,113,118,0,8,114.86937276552204,4.990419433418533,1.1339619614241,1.6150827207972682,-0.03546165985386551,0.0,0.0,0.0,1.2718814611434937,1.063655138015747,-1.4976170063018799,0.8824697136878967,0.6195887923240662,0.0387519970536232,21455.66015625,21767.90234375,2811.4970703125,5796.5703125,115,5,115,5,2 -50.0,15,11,23,26,6,10,24.28275827424409,8.039976058228342,0.8405378949206057,0.8511908285323688,-0.07544512810187864,0.0,0.0,0.0,0.9599465131759644,0.8776283264160156,-0.820639967918396,1.1992552280426025,1.1842461824417114,0.2125914990901947,2039.9886474609375,2240.87744140625,303.15179443359375,625.5487670898438,24,8,24,8,0 -50.0,9,7,234,237,8,10,235.40642767024428,9.042625708551148,0.6428553455751191,0.5167304730277666,-0.08661423171368776,0.0,0.0,0.0,0.828813910484314,0.6874978542327881,-0.4707348048686981,1.5915024280548096,1.979960322380066,0.5335344672203064,917.0333251953125,1095.7138671875,156.95762634277344,312.5994567871094,235,9,235,9,0 -50.0,76,69,216,230,0,11,224.2337614941604,3.6750143356491303,1.9833180625025761,1.9112836336963923,-0.330688447211287,0.0,0.0,0.0,1.5099486112594604,1.2706913948059082,-0.7311540842056274,0.5191830992698669,0.5387506484985352,0.17965713143348694,69923.6640625,70452.359375,8391.15234375,18264.26171875,224,4,224,4,3 -50.0,13,5,48,51,8,11,49.29498513567114,9.579522186060807,0.7811015056450543,0.7338449126616338,-0.07717714376701679,0.0,0.0,0.0,0.9155251383781433,0.8226543068885803,-0.6368504166603088,1.2936862707138062,1.3769943714141846,0.2721092998981476,1406.0142822265625,1528.1524658203125,200.69036865234375,398.20513916015625,49,10,49,10,1 -50.0,8,6,45,47,10,12,45.54553440506677,10.546745526006521,0.6101083364527218,0.5627965527128389,-0.002046711732975104,0.0,0.0,0.0,0.7811508774757385,0.7501387596130371,-0.04315262287855148,1.639073133468628,1.7768627405166626,0.011921573430299759,833.1487426757812,1064.1783447265625,159.06689453125,306.486328125,46,11,46,11,1 -50.0,6,5,173,175,13,15,174.1774838142405,13.845774245018491,0.4531263062670292,0.3999572321995869,-0.10490043565746177,0.0,0.0,0.0,0.7312717437744141,0.5642030835151672,-0.6612977385520935,2.3495516777038574,2.661893844604492,1.2324767112731934,410.2804870605469,552.0734252929688,91.86316680908203,157.32757568359375,174,14,174,14,0 -50.0,17,10,217,221,15,18,218.59380071865456,16.690688792818605,0.9134654583149615,0.8038509158032032,0.03687303396073682,0.0,0.0,0.0,0.9616208672523499,0.8902817964553833,0.29611021280288696,1.0967628955841064,1.2463194131851196,-0.10061810165643692,3859.174072265625,4076.819091796875,539.1503295898438,977.026611328125,219,17,218,17,0 -50.0,66,62,225,234,10,18,228.56050765030483,14.088255172253863,1.502205697375837,1.3925554636405515,0.021590234818487986,0.0,0.0,0.0,1.2273156642913818,1.178328275680542,0.18757589161396027,0.6658361554145813,0.7182642817497253,-0.02064630016684532,67158.546875,67486.921875,8086.74951171875,16100.947265625,228,14,228,14,0 -50.0,8,7,23,26,17,19,24.516467611021227,18.019639288649717,0.5598246850289001,0.47621993820408903,0.0037544320714382184,0.0,0.0,0.0,0.7483267784118652,0.689965009689331,0.044786758720874786,1.7863678932189941,2.0999810695648193,-0.02816680446267128,847.74267578125,1081.5911865234375,156.7303466796875,297.5451354980469,25,18,24,18,0 -50.0,18,10,153,157,15,19,155.08337548365088,17.607303816768674,1.1722576398588034,0.9690543744894295,0.062422898590726916,0.0,0.0,0.0,1.090826153755188,0.9754027128219604,0.2754661738872528,0.855991005897522,1.0354857444763184,-0.11027954518795013,2161.434326171875,2389.12255859375,256.41412353515625,369.4764099121094,155,18,155,18,0 -50.0,17,11,160,164,16,19,161.7809183197715,17.606519470954176,1.0390375651455548,0.8581677171312174,-0.08751822712577617,0.0,0.0,0.0,1.0365574359893799,0.9070578217506409,-0.38450467586517334,0.9707680344581604,1.1753698587417603,0.19800300896167755,2408.703125,2611.041748046875,308.59869384765625,554.89599609375,162,18,162,18,1 -50.0,7,6,139,141,21,23,139.64770425282836,21.94058918793172,0.4116663930643147,0.5094645587149872,0.009739822218785332,0.0,0.0,0.0,0.7144404053688049,0.6408633589744568,1.4724918603897095,2.430250644683838,1.9637333154678345,-0.0929219052195549,601.0863647460938,819.606201171875,121.87938690185547,224.46046447753906,140,22,140,22,0 -50.0,10,8,14,17,22,24,15.826917278277437,22.89947398972195,0.6833738231749424,0.5307021085078937,0.00506408003513803,0.0,0.0,0.0,0.826765775680542,0.7283778786659241,0.033121202141046524,1.4634313583374023,1.8844295740127563,-0.0279287900775671,1258.536865234375,1485.907470703125,225.92474365234375,467.6408386230469,16,23,16,23,0 -50.0,109,101,88,100,14,26,93.84482216790566,18.71217557363722,1.6750879778035568,1.6279698377743088,0.07106289606997507,0.0,0.0,0.0,1.3139235973358154,1.2556523084640503,0.6253374218940735,0.5980911254882812,0.6154016256332397,-0.052214834839105606,196665.453125,197147.0,24008.193359375,46438.609375,94,19,94,19,0 -50.0,13,10,253,255,22,26,254.1248305845004,24.286591019425682,0.5372122931634586,0.919289843780402,0.017590825280915823,0.0,0.0,0.0,0.959217369556427,0.732396125793457,1.524885892868042,1.8626285791397095,1.0884782075881958,-0.07128366082906723,2924.821533203125,3343.180908203125,475.5140380859375,920.9725952148438,254,24,254,24,2 -50.0,17,16,129,133,23,27,130.52434268055254,24.30790603431951,1.0094507259787076,1.0260058576910438,-0.16393087895477687,0.0,0.0,0.0,1.0871375799179077,0.9238985776901245,-0.8106238842010498,1.0170265436172485,1.0006163120269775,0.3249923884868622,2336.107666015625,2637.304931640625,282.43426513671875,541.0640869140625,131,24,130,24,0 -50.0,14,8,22,25,25,28,23.787253206000553,26.422919375311164,0.7749907884450931,0.7888200367901423,-0.005957854751716507,0.0,0.0,0.0,0.8894001841545105,0.8790779709815979,-1.215192437171936,1.2904129028320312,1.2677898406982422,0.01949263922870159,1707.004150390625,1824.630859375,249.18128967285156,474.3712158203125,24,26,24,26,0 -50.0,20,13,59,63,24,28,60.472423903513125,26.080421592507196,0.9069569637068873,0.9560407979516352,0.05325823194873802,0.0,0.0,0.0,0.9950576424598694,0.9342687129974365,1.001301646232605,1.1062067747116089,1.0494133234024048,-0.12324707955121994,5779.17724609375,6038.96484375,794.75,1601.638916015625,60,26,60,26,0 -50.0,15,10,169,173,25,28,171.05324233076618,26.438043432723916,0.864842017182843,0.8009424366791458,0.04649013373947852,0.0,0.0,0.0,0.9430283904075623,0.8811821341514587,0.48434343934059143,1.1598997116088867,1.2524369955062866,-0.13465110957622528,2075.346923828125,2252.385498046875,291.2528381347656,545.0776977539062,171,26,171,26,0 -50.0,28,23,30,35,20,25,31.918311232168467,22.605127590317878,1.1321385542838014,1.0995269284525975,0.023818019958133263,0.0,0.0,0.0,1.069905400276184,1.0425775051116943,0.48524048924446106,0.8836868405342102,0.909896731376648,-0.03828495740890503,10617.392578125,10791.326171875,1363.83056640625,2681.29296875,32,23,32,23,1 -50.0,18,11,33,37,25,29,35.00379151259828,27.52797134038642,0.9642577390518614,0.9224869474886521,0.11075150409135759,0.0,0.0,0.0,1.0276556015014648,0.9114103317260742,0.692203164100647,1.0515676736831665,1.0991833209991455,-0.25249722599983215,2958.20849609375,3085.3447265625,397.83575439453125,794.6194458007812,35,28,35,28,1 -50.0,16,11,238,241,25,29,239.36631729570396,27.24857563704441,0.8011171620566049,0.8694947048666251,-0.006008455746170149,0.0,0.0,0.0,0.9327479004859924,0.8947587609291077,-1.4838128089904785,1.248321533203125,1.1501529216766357,0.017252514138817787,3376.062744140625,3610.586181640625,486.54345703125,938.9769287109375,239,27,239,27,0 -50.0,15,9,201,204,28,31,202.50487897900285,29.356107118738887,0.8381153706205069,0.8006351686310129,0.06585336923646912,0.0,0.0,0.0,0.9422543048858643,0.8665490746498108,0.646776020526886,1.2009143829345703,1.257132887840271,-0.19755379855632782,2515.47802734375,2693.14208984375,346.084716796875,635.2933349609375,202,29,202,29,0 -50.0,27,21,112,118,24,28,114.64613281327082,25.855930618944388,1.7358508113999704,1.0369425449762142,-0.07636840113610877,0.0,0.0,0.0,1.3206430673599243,1.0142461061477661,-0.10757685452699661,0.5779590010643005,0.9675084352493286,0.08513066917657852,5105.04931640625,5380.66455078125,553.1353149414062,1097.051513671875,114,26,114,26,1 -50.0,14,11,116,119,28,32,117.0575564013912,29.979984985605896,0.774335811658867,0.9513706255132357,0.050340463593828266,0.0,0.0,0.0,0.9821832180023193,0.8723660111427307,1.3122503757476807,1.2958872318267822,1.0547434091567993,-0.1371401697397232,1847.6683349609375,1987.665283203125,278.5109558105469,607.0015869140625,117,30,117,30,1 -50.0,14,9,228,231,28,32,229.6511454212427,29.765057832632376,0.7671846838638823,0.8806486982262229,0.12457552893256318,0.0,0.0,0.0,0.9802050590515137,0.8288735747337341,0.999066948890686,1.3341118097305298,1.162222981452942,-0.37744376063346863,2053.497314453125,2310.5166015625,275.68896484375,500.99884033203125,230,30,229,30,0 -50.0,27,20,1,6,27,33,3.138045683311431,29.547896887648367,1.8486087243633165,1.7433815629800566,0.36688344991842303,0.0,0.0,0.0,1.4719483852386475,1.1938836574554443,0.7141803503036499,0.5645250678062439,0.5985987186431885,-0.2376013547182083,3370.215087890625,3685.370849609375,267.0796203613281,558.2594604492188,2,29,2,29,0 -50.0,29,19,105,110,29,34,107.35954318380979,31.69595173849561,1.0985181266315616,1.026324658267117,0.0726512153329848,0.0,0.0,0.0,1.0693670511245728,0.9906043410301208,0.554836094379425,0.9145990610122681,0.9789335131645203,-0.12948481738567352,14668.310546875,14842.103515625,1938.0880126953125,4097.03857421875,107,32,107,32,0 -50.0,13,8,84,87,32,35,85.35101394485109,33.30183320275938,0.7535910812884299,0.7361779811133433,0.07798820181502175,0.0,0.0,0.0,0.9073903560638428,0.8163405060768127,0.7298086881637573,1.341688871383667,1.3734244108200073,-0.28426796197891235,1749.462646484375,1950.772705078125,263.27227783203125,498.4325866699219,85,33,85,33,0 -50.0,7,6,29,31,34,36,29.63988818667963,35.05811876771811,0.4111268268135102,0.513991457730899,-0.012706432392483258,0.0,0.0,0.0,0.7180095911026001,0.6399847865104675,-1.4496954679489136,2.434199333190918,1.9470452070236206,0.12035214900970459,601.63232421875,811.2866821289062,119.08899688720703,214.39247131347656,30,35,29,35,0 -50.0,15,9,65,69,34,37,67.09615837575149,35.357650253228265,0.8170719045556938,0.7818275268228021,0.03307084265812499,0.0,0.0,0.0,0.9148347973823547,0.8729128241539001,0.5406031012535095,1.2259814739227295,1.2812480926513672,-0.10371658205986023,2697.53955078125,2922.6357421875,411.977783203125,841.0968017578125,67,35,67,35,0 -50.0,15,9,188,191,36,39,189.49881324312017,37.62595007461462,0.8354017701798844,0.8031177307819677,0.05632304876863703,0.0,0.0,0.0,0.9369366765022278,0.8721635341644287,0.6458403468132019,1.202715516090393,1.2510627508163452,-0.16869407892227173,2435.529052734375,2621.033935546875,328.7482604980469,595.1300659179688,190,38,189,38,0 -50.0,13,8,166,169,39,42,167.47995701745006,40.57998977552677,0.7595805811592138,0.7787889957671803,0.10732155726178094,0.0,0.0,0.0,0.9364482164382935,0.8132861256599426,0.8300243020057678,1.3426584005355835,1.3095425367355347,-0.37005195021629333,1463.620849609375,1656.0927734375,203.48394775390625,371.1052551269531,167,40,167,40,0 -50.0,9,7,124,127,41,43,125.64310951563037,41.96074884940261,0.657317198260257,0.5138933165682542,-0.09271643344963487,0.0,0.0,0.0,0.8383427262306213,0.6843917369842529,-0.45622628927230835,1.5610625743865967,1.9967436790466309,0.5632925629615784,834.4611206054688,1016.3577880859375,144.35044860839844,259.8595886230469,126,42,126,42,0 -50.0,15,13,213,216,40,43,214.38520362344713,41.6243124833056,0.8599775060647248,0.8772789649845594,0.05878337002519185,0.0,0.0,0.0,0.963350772857666,0.8995620012283325,0.858455240726471,1.1681715250015259,1.1451332569122314,-0.1565501093864441,2226.51953125,2438.99951171875,286.7843017578125,529.20654296875,214,42,214,42,0 -50.0,19,11,235,238,40,45,236.3316687724673,42.0387961940396,0.8091427537903626,1.2718613068571152,-0.007627046413963168,0.0,0.0,0.0,1.1278239488601685,0.8994537591934204,-1.554319143295288,1.235945701599121,0.7862936854362488,0.014823338948190212,2634.238037109375,2838.71435546875,347.92169189453125,739.4152221679688,236,42,236,42,0 -50.0,25,15,245,249,40,45,247.0509606506648,42.300678547047625,1.0008769023840927,1.0846254734911183,0.06734206617119298,0.0,0.0,0.0,1.0592689514160156,0.9815557599067688,1.0635509490966797,1.0033152103424072,0.9258449077606201,-0.12458737194538116,9458.54296875,9667.8818359375,1280.7301025390625,2621.508544921875,247,42,247,42,0 -50.0,22,20,0,5,44,47,2.4761856925143966,45.56938154246253,1.48505970993034,0.8373359882861058,-0.04531089758080942,0.0,0.0,0.0,1.219923734664917,0.9133354425430298,-0.06950290501117706,0.6744872331619263,1.1962387561798096,0.07299727201461792,5558.3125,5869.49658203125,577.5806884765625,1005.8999633789062,3,45,3,45,2 -50.0,12,7,71,74,44,47,72.44041674615765,45.52012474283593,0.7361072569391864,0.7225140783480102,-0.023501087058951153,0.0,0.0,0.0,0.8682020902633667,0.8395513892173767,-0.6446370482444763,1.3599098920822144,1.3854948282241821,0.08846709132194519,1065.3570556640625,1238.1021728515625,152.89544677734375,301.74163818359375,72,46,72,46,0 -50.0,12,8,13,15,46,49,13.956032843400246,47.47933543873104,0.5666816657132139,0.8296613800715646,0.013913613951592962,0.0,0.0,0.0,0.9112603664398193,0.7522948980331421,1.5180848836898804,1.7653861045837402,1.2058075666427612,-0.05921186879277229,1700.563720703125,1933.8426513671875,264.69915771484375,495.77288818359375,14,47,14,47,0 -50.0,17,9,17,21,46,50,18.73373530494359,48.01186026725182,0.8808656292347519,0.8594077424933495,0.007589631281034848,0.0,0.0,0.0,0.9398291110992432,0.9257400631904602,0.3078368604183197,1.1353332996368408,1.1636805534362793,-0.02005278877913952,2611.15869140625,2764.135009765625,388.3087463378906,805.161865234375,19,48,19,48,0 -50.0,11,7,224,227,48,50,225.39371587548962,49.114154985285886,0.8018578816194286,0.5385803478218647,0.08793922642216612,0.0,0.0,0.0,0.9102357625961304,0.7154781818389893,0.29447445273399353,1.2698426246643066,1.8905874490737915,-0.4146789610385895,1212.8955078125,1416.5775146484375,195.40931701660156,374.6084289550781,225,49,225,49,0 -50.0,14,9,59,63,48,51,60.83037831239659,49.71042031650599,0.8290003874873739,0.729749887424088,0.0934469901375028,0.0,0.0,0.0,0.9408408999443054,0.8207123279571533,0.5413082242012024,1.223939061164856,1.3904023170471191,-0.31345921754837036,2096.46875,2298.598388671875,325.4040222167969,666.4501342773438,61,50,61,50,0 -50.0,20,12,93,97,47,51,94.92480124700985,49.41822874186798,1.0545204435309712,0.9528257220191989,0.10934074317807863,0.0,0.0,0.0,1.0603106021881104,0.9397274255752563,0.5677546262741089,0.9597176313400269,1.0621479749679565,-0.22026324272155762,4108.7529296875,4303.5419921875,547.3841552734375,1059.0059814453125,95,49,95,49,1 -50.0,8,6,98,100,51,53,99.42703330598492,51.53356836899677,0.625734637684932,0.5534324898849132,0.018586468084351493,0.0,0.0,0.0,0.7938719987869263,0.7409010529518127,0.23744507133960724,1.599717378616333,1.8087093830108643,-0.10744976252317429,722.9559936523438,914.8157958984375,137.43373107910156,283.7413330078125,99,52,99,52,1 -50.0,19,11,145,149,47,50,146.96078808007812,48.40604646045614,1.0430590621143407,0.8510119921007098,0.0687776298178373,0.0,0.0,0.0,1.0320607423782349,0.910451352596283,0.31077712774276733,0.9638549089431763,1.1813671588897705,-0.1557948887348175,3701.98291015625,3831.911376953125,511.8498229980469,1004.6756591796875,147,48,147,48,1 -50.0,18,12,149,153,50,54,151.3033963816303,51.71025841498351,0.9412186795316266,0.8436698810918024,0.0693002946124941,0.0,0.0,0.0,0.9885281324386597,0.8987216949462891,0.47875818610191345,1.0689170360565186,1.1925100088119507,-0.17560486495494843,4193.7548828125,4420.29443359375,604.2129516601562,1290.567138671875,151,52,151,52,1 -50.0,12,7,165,168,51,54,166.54053258483125,52.516488960729454,0.7002578079577098,0.689350681604425,0.0022870336366329624,0.0,0.0,0.0,0.837088942527771,0.8299943208694458,0.19854405522346497,1.4280610084533691,1.4506561756134033,-0.009475651197135448,1554.564208984375,1752.8348388671875,222.9730224609375,390.04931640625,167,53,166,53,0 -50.0,25,18,67,72,51,55,69.46085324206764,53.23468279339415,1.0716145495113976,0.9633492557749248,0.05273774687221344,0.0,0.0,0.0,1.045493721961975,0.9705187678337097,0.3861733376979828,0.9356922507286072,1.0408493280410767,-0.10244737565517426,10252.1259765625,10484.474609375,1312.6651611328125,2427.605224609375,69,53,69,53,0 -50.0,10,8,7,9,54,57,8.051030313539993,55.83749534946756,0.5383778125120313,0.6861066262596216,0.014470660351000753,0.0,0.0,0.0,0.8291626572608948,0.7327848672866821,1.474067211151123,1.858485221862793,1.4583261013031006,-0.07839454710483551,1196.6114501953125,1414.768310546875,215.78485107421875,468.6285705566406,8,56,8,56,0 -50.0,87,78,52,63,36,47,56.977373115124195,41.15714144273605,1.4969176587215784,1.4585719460038362,0.015442437306173673,0.0,0.0,0.0,1.225709319114685,1.2054569721221924,0.33902227878570557,0.6681123971939087,0.6856769919395447,-0.01414710283279419,172536.3125,172752.734375,22535.9140625,46960.18359375,57,41,57,41,1 -50.0,163,143,42,56,40,57,47.223891429479,46.57012346057515,2.9049694399825725,3.3945317945306215,0.40854302795061415,0.0,0.0,0.0,1.9042091369628906,1.6350806951522827,1.055297613143921,0.35016459226608276,0.2996635437011719,-0.08428691327571869,321544.15625,322267.125,34535.78125,67714.1875,47,47,47,47,1 -50.0,7,5,89,91,55,57,89.64536644187062,55.89973266663557,0.41434291701749504,0.5019963983199351,0.011361433325170589,0.0,0.0,0.0,0.7095386385917664,0.6425684690475464,1.4439705610275269,2.4149584770202637,1.9932831525802612,-0.10931310057640076,580.9573974609375,791.7469482421875,116.52233123779297,219.31683349609375,90,56,89,56,0 -50.0,11,8,159,162,55,58,160.44964205797234,56.93932567436033,0.6929834822572163,0.7861977907366917,0.09642745192232649,0.0,0.0,0.0,0.9201581478118896,0.7952926158905029,1.0105133056640625,1.4680911302566528,1.2940292358398438,-0.3601238429546356,1226.863525390625,1379.9837646484375,199.65731811523438,431.7133483886719,160,57,160,57,1 -50.0,11,9,93,96,56,59,94.15009669701031,57.153509855759374,0.670567792233935,0.66410238642141,-0.009801305769780999,0.0,0.0,0.0,0.8231984972953796,0.8105642795562744,-0.6261038780212402,1.4915952682495117,1.5061168670654297,0.04402809590101242,1407.7969970703125,1636.2401123046875,240.769775390625,513.7340087890625,94,57,94,57,0 -50.0,22,12,103,107,55,59,104.91579884080637,56.91409798199792,0.9846030040611904,0.9507944234530372,0.06474862543136295,0.0,0.0,0.0,1.0171616077423096,0.9490941762924194,0.6577104926109314,1.0202065706253052,1.056483268737793,-0.1389511078596115,6871.8740234375,7065.12255859375,1007.0591430664062,2183.01513671875,105,57,105,57,0 -50.0,50,46,214,220,52,59,216.4629046476085,55.67415300999521,1.3819589953399936,1.4088104309728493,-0.03545439510859616,0.0,0.0,0.0,1.1972033977508545,1.1651066541671753,-0.9663928151130676,0.7240779399871826,0.7102773189544678,0.03644457086920738,34570.99609375,34887.70703125,4247.24267578125,9002.8076171875,216,56,216,56,0 -50.0,9,8,40,42,59,61,41.00061763584925,60.094045313159334,0.5616054462921922,0.553538222772366,0.00992284506663399,0.0,0.0,0.0,0.7538455724716187,0.7395001649856567,0.5923506021499634,1.7811737060546875,1.807132363319397,-0.06385940313339233,851.6484375,1044.9241943359375,163.22657775878906,353.2093200683594,41,60,41,60,0 -50.0,63,57,127,135,53,61,130.37308455507525,56.53509318361332,1.467163165872952,1.3981465188778301,-0.019976349082382328,0.0,0.0,0.0,1.2134777307510376,1.180161714553833,-0.26237452030181885,0.6817200779914856,0.7153717875480652,0.019480474293231964,62403.1796875,62752.5546875,7278.7900390625,14467.5791015625,130,57,130,57,0 -50.0,13,9,184,187,57,61,184.9757055586017,59.18976686564385,0.6513809379132489,1.0225203026597995,0.06859946939422912,0.0,0.0,0.0,1.017248272895813,0.7994418740272522,1.3937517404556274,1.5461238622665405,0.9849346280097961,-0.2074546217918396,1524.827392578125,1717.673583984375,219.1380157470703,410.9485778808594,185,59,185,59,1 -50.0,10,8,194,196,58,61,195.04256859908875,59.25787466012304,0.5255982063735514,0.7136025967112325,0.007317108340967549,0.0,0.0,0.0,0.8449183106422424,0.7247853875160217,1.5319547653198242,1.9028656482696533,1.4015402793884277,-0.03902304917573929,1160.1326904296875,1367.75439453125,205.01199340820312,427.35162353515625,195,59,195,59,0 -50.0,8,6,123,125,64,66,123.9029236348633,65.24011878085285,0.5300989608979513,0.4956167516092249,0.07619471171050995,0.0,0.0,0.0,0.7687515020370483,0.659345805644989,0.6741334199905396,1.9290682077407837,2.063281774520874,-0.5931389331817627,837.5856323242188,1092.0408935546875,163.5234375,323.2138366699219,124,65,124,65,0 -50.0,15,13,24,27,61,64,25.471394787817324,62.49345493887951,0.8703278207725669,0.8660404407062146,0.040044241479997744,0.0,0.0,0.0,0.9530402421951294,0.9099904298782349,0.7586571574211121,1.1514419317245483,1.1571422815322876,-0.10648144781589508,2651.9921875,2775.0048828125,324.4437561035156,538.3921508789062,25,62,25,62,1 -50.0,39,30,19,25,62,68,21.59133405804307,65.13671622609371,1.2427718065030842,1.1913657900453458,0.07078906294143472,0.0,0.0,0.0,1.1368287801742554,1.0685306787490845,0.6112526655197144,0.8073855638504028,0.8422232866287231,-0.09594713151454926,25184.7421875,25334.33984375,3122.0009765625,5875.47607421875,22,65,22,65,1 -50.0,10,7,26,29,58,60,27.491323680519947,58.55856315524052,0.7492096870996856,0.6736415383788206,-0.08867243643268985,0.0,0.0,0.0,0.8987839221954346,0.7842440009117126,-0.5839936137199402,1.355863094329834,1.5079618692398071,0.3569485545158386,955.2809448242188,1118.2796630859375,155.5791778564453,308.62786865234375,27,59,27,59,1 -50.0,18,14,104,108,64,68,106.02919395964936,66.61942125482607,1.0036534963329728,0.9604757627664862,-0.1501285152959868,0.0,0.0,0.0,1.064771056175232,0.911258339881897,-0.7139864563941956,1.020213007926941,1.0660761594772339,0.3189316689968109,2618.6826171875,2851.310302734375,377.5166320800781,806.5936889648438,106,67,106,67,0 -50.0,9,7,79,81,68,70,80.10851232262624,69.02726015930983,0.5500804545432438,0.5578778542457579,0.012770308303258204,0.0,0.0,0.0,0.7532140016555786,0.7352734208106995,0.9335514903068542,1.8188824653625488,1.7934601306915283,-0.08327160030603409,1006.523681640625,1229.451171875,194.29949951171875,427.06756591796875,80,69,80,69,0 -50.0,33,25,149,156,64,70,153.42859622774512,67.37664614489451,1.4504359372000692,1.169590076789163,0.27460903989347685,0.0,0.0,0.0,1.272180199623108,1.0007914304733276,0.5490527153015137,0.7215214371681213,0.8947755098342896,-0.33881324529647827,15171.908203125,15470.4638671875,1795.1807861328125,3164.70703125,153,67,153,67,1 -50.0,16,13,156,159,66,70,157.30622665177407,68.32963748612804,0.8502785156118016,0.9337287126780325,-0.01353694163783059,0.0,0.0,0.0,0.9674035906791687,0.9209438562393188,-1.4139374494552612,1.1763567924499512,1.071222186088562,0.03410899266600609,3557.564697265625,3660.7744140625,457.5765380859375,735.7101440429688,157,68,157,69,1 -50.0,74,67,2,12,62,71,5.195704482303576,66.29171404162335,1.7292002464023515,1.4230270891299988,-0.09714625402166277,0.0,0.0,0.0,1.3256781101226807,1.181018590927124,-0.28273066878318787,0.5805284976959229,0.7054328322410583,0.07926225662231445,81294.7421875,81700.15625,10058.7578125,19621.380859375,5,66,5,66,0 -50.0,14,8,84,87,68,71,85.57824631568263,69.13076337242322,0.8295632050851824,0.7333437537700416,0.003226769595548795,0.0,0.0,0.0,0.910862922668457,0.8562918305397034,0.03348537161946297,1.2054742574691772,1.363640308380127,-0.010608361102640629,1968.2142333984375,2133.042724609375,289.70623779296875,551.9159545898438,86,69,86,69,0 -50.0,57,48,164,172,62,71,166.50927893844835,65.0752726144766,1.5195077008902595,1.7592777584139903,0.1266158403322546,0.0,0.0,0.0,1.3467590808868408,1.210382342338562,1.1644479036331177,0.6620784401893616,0.5718444585800171,-0.09530003368854523,35400.8671875,35800.9921875,4423.03125,9400.8642578125,166,65,166,65,0 -50.0,10,7,66,68,69,72,67.01806413419433,70.73085173499247,0.5333069599774289,0.6772356976219149,0.004151956553830161,0.0,0.0,0.0,0.8230160474777222,0.7301967740058899,1.5419809818267822,1.8751822710037231,1.4766613245010376,-0.022992512211203575,1322.1046142578125,1562.8729248046875,235.5998992919922,500.8076171875,67,71,67,71,0 -50.0,14,8,58,61,71,74,59.85062398348071,72.40299530139922,0.7385243744948697,0.8027311077066484,-0.006271898531395426,0.0,0.0,0.0,0.8962912559509277,0.8590212464332581,-1.4743285179138184,1.354141354560852,1.2458298206329346,0.02116035297513008,2089.2060546875,2294.90576171875,317.01336669921875,619.7683715820312,60,72,60,72,0 -50.0,26,21,177,181,69,74,178.6933618135844,71.31605586489381,1.0189053623689217,1.062749672341841,0.04145553638985078,0.0,0.0,0.0,1.0429394245147705,0.9969616532325745,1.0286132097244263,0.9830055236816406,0.9424511194229126,-0.07668978720903397,13669.7060546875,13943.7724609375,1739.66650390625,3228.960693359375,179,71,179,71,0 -50.0,11,8,42,45,72,75,43.877042529189396,73.21124353595184,0.6654814456091098,0.6540522241419648,0.028459538470159362,0.0,0.0,0.0,0.8299363851547241,0.7941909432411194,0.6863169074058533,1.5054728984832764,1.5317802429199219,-0.13101419806480408,1370.1412353515625,1572.4598388671875,233.10621643066406,481.9030456542969,44,73,44,73,0 -50.0,30,24,91,97,71,76,93.75739878246443,73.22996858846885,1.2299943384785692,1.0013971645985533,0.055829740283432905,0.0,0.0,0.0,1.1148545742034912,0.994228720664978,0.22718459367752075,0.8150745034217834,1.0011382102966309,-0.09088381379842758,15756.125,16065.4169921875,2061.076904296875,4095.904052734375,94,73,94,73,0 -50.0,10,9,217,219,71,74,218.00054726248524,71.98650571701995,0.5362554845780605,0.721491851807345,0.008925413175077335,0.0,0.0,0.0,0.8496593236923218,0.7320016622543335,1.5227607488632202,1.8651667833328247,1.3863024711608887,-0.04614711552858353,1391.00634765625,1626.3865966796875,254.927734375,566.6343994140625,218,72,218,72,1 -50.0,9,7,217,219,75,77,217.9478510439735,75.9919783782912,0.5619779369654685,0.5604996066885575,0.009851893445381177,0.0,0.0,0.0,0.7557237148284912,0.7425356507301331,0.7479544281959534,1.779977798461914,1.784672498703003,-0.06257328391075134,1078.4613037109375,1317.1070556640625,206.67774963378906,453.1005554199219,218,76,218,76,1 -50.0,8,6,47,49,76,78,47.79085466451151,76.8089454342448,0.5133871864300844,0.510671168058922,-0.07188383896861639,0.0,0.0,0.0,0.7641503810882568,0.6634248495101929,-0.7759534120559692,1.9870105981826782,1.9975786209106445,0.5593969821929932,695.6636352539062,913.7842407226562,133.92286682128906,252.3525390625,48,77,48,77,0 -50.0,9,5,141,144,76,78,142.36032221430253,77.1545758660588,0.6415412774423119,0.4820316832882865,-0.06738668754696553,0.0,0.0,0.0,0.816209614276886,0.6762949228286743,-0.35076969861984253,1.581976056098938,2.1054694652557373,0.44231170415878296,838.838134765625,1036.4700927734375,154.60580444335938,312.07562255859375,142,77,142,77,0 -50.0,10,8,87,90,79,81,88.1653341715922,79.9571696146629,0.684415026265891,0.5406726574817833,0.026176952940744957,0.0,0.0,0.0,0.8300805687904358,0.7321570515632629,0.1746433824300766,1.4638123512268066,1.8529791831970215,-0.1417424976825714,1180.4010009765625,1414.655029296875,213.514404296875,467.6927490234375,88,80,88,80,0 -50.0,9,7,78,80,82,84,79.04175136982175,83.0393825406318,0.5706544281156345,0.5651450910220277,0.03715521892995444,0.0,0.0,0.0,0.7779183387756348,0.7284521460533142,0.748396098613739,1.7599074840545654,1.7770640850067139,-0.2314087152481079,830.765380859375,1015.76806640625,155.10055541992188,333.9854431152344,79,83,79,83,0 -50.0,25,20,107,113,77,81,108.88842423873606,79.17280305430822,1.785222009603622,1.0616497658205226,-0.0807021864612647,0.0,0.0,0.0,1.3394453525543213,1.026039958000183,-0.10973644256591797,0.5620859265327454,0.945178210735321,0.08545485883951187,6755.16455078125,6982.85205078125,825.798828125,1655.419189453125,109,79,109,79,1 -50.0,32,23,150,155,81,86,152.1974648530485,83.47855780444054,1.1578180256808395,1.0980180311684826,0.06868095886643033,0.0,0.0,0.0,1.0967339277267456,1.0261632204055786,0.5800975561141968,0.8669101595878601,0.9141236543655396,-0.10845035314559937,16781.634765625,16968.42578125,2068.40576171875,4043.670166015625,152,84,152,84,0 -50.0,7,7,14,16,87,89,14.648015549212378,88.04774116757955,0.41232337129150837,0.5029937688718324,-0.0025578694474946984,0.0,0.0,0.0,0.7092713713645935,0.6420679688453674,-1.542615532875061,2.4253573417663574,1.988158941268921,0.024667294695973396,724.357177734375,995.530517578125,149.76060485839844,289.57769775390625,15,88,15,88,0 -50.0,14,9,96,99,86,89,97.25516557185635,87.48751822880759,0.8143645244476134,0.7897050455080259,0.00010588240433295759,0.0,0.0,0.0,0.9024217128753662,0.8886532187461853,0.004293675534427166,1.2279514074325562,1.2662955522537231,-0.0003292835608590394,1711.3060302734375,1896.0279541015625,232.48220825195312,435.7843322753906,97,88,97,88,0 -50.0,9,6,63,65,87,90,63.91101321094338,88.41756739752309,0.49954666032220585,0.6336425824108942,0.07608985776886179,0.0,0.0,0.0,0.817318856716156,0.6820404529571533,1.1465545892715454,2.039112091064453,1.6075807809829712,-0.48972639441490173,968.158203125,1218.299072265625,170.5127716064453,321.2797546386719,64,88,64,89,0 -50.0,13,11,104,108,87,90,106.04510276435374,88.31061962710878,0.835999005152809,0.8745452415800146,-0.2557868777444381,0.0,0.0,0.0,1.054411768913269,0.7737959623336792,-0.8230012655258179,1.313738465309143,1.2558344602584839,0.7684841156005859,1646.21044921875,1939.4110107421875,254.838623046875,549.1564331054688,106,88,106,88,0 -50.0,17,10,26,30,88,91,27.879999781256902,89.37392648745306,0.9497261240421548,0.7932386011556496,0.05976908602428743,0.0,0.0,0.0,0.9848566651344299,0.879216730594635,0.3261636197566986,1.057951807975769,1.2666610479354858,-0.15942949056625366,3592.46826171875,3800.549560546875,512.724853515625,1006.6282348632812,28,89,28,89,0 -50.0,21,15,218,222,85,89,219.6582370468568,86.70334508375764,0.9609658865955879,0.9624933975107233,-0.026076243593020187,0.0,0.0,0.0,0.9938898682594299,0.9672859907150269,-0.8000386357307434,1.041385293006897,1.039732575416565,0.05642722547054291,6508.708984375,6717.06884765625,865.6270751953125,1557.2886962890625,220,87,220,87,1 -50.0,8,6,216,218,89,91,216.51293705820325,90.47539762759774,0.6222266029342108,0.5566499329186794,-0.005736943827485685,0.0,0.0,0.0,0.7891290783882141,0.7457558512687683,-0.08660782128572464,1.6072843074798584,1.796631932258606,0.0331299751996994,668.6237182617188,879.9554443359375,117.0981216430664,194.0494384765625,217,90,216,90,1 -50.0,16,14,177,181,91,94,179.14322339794745,92.3744318839427,1.0522360516009215,0.9589421393602056,-0.1495375051107053,0.0,0.0,0.0,1.0780692100524902,0.9213820695877075,-0.6342101693153381,0.9718955159187317,1.0664496421813965,0.3031149208545685,2779.484130859375,2986.239501953125,348.6236877441406,671.0993041992188,179,92,179,92,1 -50.0,23,17,167,172,86,90,168.4654353810782,88.31031799281416,1.3929913132877658,0.9596075792193588,-0.08929948966177514,0.0,0.0,0.0,1.1877164840698242,0.9705299735069275,-0.1954483687877655,0.722187876701355,1.0483466386795044,0.13441121578216553,4630.74755859375,4749.01806640625,558.1131591796875,1015.4046630859375,168,88,168,88,1 -50.0,10,8,133,136,97,99,134.74704339655744,98.07703542151657,0.6859764568278646,0.5311373721599566,0.016719320445870878,0.0,0.0,0.0,0.8293136954307556,0.7275662422180176,0.1063455268740654,1.4588953256607056,1.88419771194458,-0.09184718877077103,1274.63330078125,1524.8204345703125,222.54396057128906,437.97088623046875,135,98,135,98,0 -50.0,29,24,201,205,87,94,202.835290339948,90.65239790647433,1.0230684811308883,1.296209487923921,0.09114491624114063,0.0,0.0,0.0,1.1505783796310425,0.9977210760116577,1.2765469551086426,0.9836134910583496,0.7763436436653137,-0.13832852244377136,11774.513671875,11987.93359375,1531.090087890625,3031.0244140625,203,91,203,91,1 -50.0,21,14,202,206,94,99,203.52126512006393,96.60463994706996,0.9442969167013784,0.9745449621382356,0.0009082061686265241,0.0,0.0,0.0,0.9872042536735535,0.971735417842865,1.5408070087432861,1.0589898824691772,1.0261207818984985,-0.0019738057162612677,6865.3095703125,7121.486328125,865.1571655273438,1689.47509765625,203,97,203,97,1 -50.0,9,6,171,173,97,100,171.8664346120726,98.62440155141257,0.49638692649763905,0.6258465638611996,-0.07120975105343441,0.0,0.0,0.0,0.8107710480690002,0.6818239092826843,-1.1542813777923584,2.0479860305786133,1.6243494749069214,0.4660457968711853,974.0839233398438,1212.732177734375,176.30551147460938,337.95672607421875,172,99,172,99,0 -50.0,11,7,66,69,100,102,67.66067055592497,100.90654579115741,0.7673251370672922,0.5507947314985254,0.06585048344512989,0.0,0.0,0.0,0.8864415884017944,0.729617178440094,0.2732256352901459,1.316738247871399,1.8343791961669922,-0.31484633684158325,1290.0072021484375,1498.432861328125,212.71163940429688,393.86181640625,68,101,68,101,0 -50.0,22,15,77,81,98,102,78.86871366577444,99.87885830261258,0.9992834991707196,0.9505438007253324,0.06690552089754176,0.0,0.0,0.0,1.0227997303009033,0.9506356120109558,0.6107449531555176,1.0054553747177124,1.0570106506347656,-0.14154110848903656,7754.2421875,7958.962890625,1118.9248046875,2367.883544921875,79,100,79,100,0 -50.0,8,5,40,42,101,103,40.741912673068185,101.81118998228389,0.49527198040464715,0.5462954183036584,-0.06524259231186358,0.0,0.0,0.0,0.7686591148376465,0.6713646650314331,-0.9717724323272705,2.0513651371002197,1.8597698211669922,0.4899780750274658,741.884521484375,957.3707275390625,130.0104217529297,204.93099975585938,41,102,41,102,0 -50.0,8,7,54,56,101,103,54.78264827362151,101.85669674218512,0.5051591883218624,0.5223047008478626,-0.06699780856526327,0.0,0.0,0.0,0.7624145746231079,0.667972981929779,-0.8490302562713623,2.0138344764709473,1.9477269649505615,0.5166428685188293,906.2811889648438,1188.52783203125,176.27432250976562,334.587158203125,55,102,55,102,0 -50.0,12,9,242,245,100,103,243.7527536572382,101.81445998815326,0.8021027987803193,0.6535279334511954,0.03092207971742944,0.0,0.0,0.0,0.8990447521209717,0.8045801520347595,0.197217658162117,1.2490012645721436,1.5329526662826538,-0.11819454282522202,1391.6761474609375,1598.8438720703125,219.20547485351562,437.7289733886719,244,102,244,102,0 -50.0,10,5,221,223,103,106,221.7491397682404,104.56892483977074,0.493859552965043,0.7291050063438087,-0.004357364737449521,0.0,0.0,0.0,0.8539236783981323,0.7026939988136292,-1.5522822141647339,2.0249738693237305,1.3716168403625488,0.02420378476381302,972.308349609375,1196.271240234375,161.86642456054688,274.14129638671875,222,105,222,105,0 -50.0,16,8,67,71,105,108,69.02102445935014,106.53128919892018,1.015518170536044,0.7624365655088998,0.00833982150153334,0.0,0.0,0.0,1.0078654289245605,0.8730189204216003,0.03290550410747528,0.9848074316978455,1.3117023706436157,-0.02154439687728882,1808.9169921875,1909.47119140625,244.28659057617188,493.1399230957031,69,107,69,107,0 -50.0,39,29,247,253,102,108,249.61954041506368,104.3398392789253,1.311809598462709,1.3140736814523546,-0.07779324274351307,0.0,0.0,0.0,1.179297685623169,1.1113686561584473,-0.7926735877990723,0.7649914026260376,0.7636733651161194,0.09057507663965225,15808.8447265625,15999.28125,1859.5679931640625,3367.139892578125,250,104,250,104,0 -50.0,5,5,132,134,108,110,132.99264946212898,109.01704611250217,0.3621322325692692,0.3546463520396568,0.00012527833434394786,0.0,0.0,0.0,0.6017760038375854,0.5955201387405396,0.016729038208723068,2.761422634124756,2.8197107315063477,-0.00195093743968755,386.0803527832031,572.7144775390625,109.21317291259766,241.79147338867188,133,109,133,109,0 -50.0,12,10,5,8,109,112,6.524235799945766,110.55177455713319,0.699443211158886,0.716228853573837,-0.0026180947893679196,0.0,0.0,0.0,0.8465386629104614,0.8360887169837952,-1.4196069240570068,1.4297281503677368,1.3962209224700928,0.010452424176037312,1654.3365478515625,1876.7392578125,235.1929168701172,454.8778991699219,7,111,6,111,0 -50.0,8,6,17,20,111,113,18.492482812107202,111.88972765678464,0.5548560524449355,0.4763477356837972,0.0017152226660488434,0.0,0.0,0.0,0.7449117302894592,0.6901523470878601,0.021833766251802444,1.802289366722107,2.099330186843872,-0.012979288585484028,700.6942138671875,904.2298583984375,129.4430389404297,252.38052368164062,18,112,18,112,0 -50.0,13,9,210,213,110,113,211.34133038181955,111.23351897652816,0.7460205196920127,0.719386414106884,0.07953491498114973,0.0,0.0,0.0,0.9018567204475403,0.8075031638145447,0.7024493217468262,1.3564339876174927,1.4066537618637085,-0.29993298649787903,1894.26611328125,2116.341064453125,301.44708251953125,624.6331176757812,211,111,211,111,0 -50.0,10,7,241,244,111,113,242.2874965364374,112.0399193768528,0.6903777608221959,0.5277007194858128,0.0016101495249105646,0.0,0.0,0.0,0.8308993577957153,0.7264191508293152,0.009896536357700825,1.4484926462173462,1.8950270414352417,-0.00883944146335125,1158.2108154296875,1383.0850830078125,204.8689727783203,433.0820007324219,242,112,242,112,0 -50.0,12,7,72,75,112,115,73.59125758454459,113.47164711018047,0.7023022130642871,0.6926882450680636,0.013818261917287078,0.0,0.0,0.0,0.8438754081726074,0.8263562917709351,0.6180093288421631,1.4244475364685059,1.4442178010940552,-0.05683188512921333,1180.620361328125,1334.765625,172.27989196777344,302.6901550292969,74,113,74,113,0 -50.0,10,7,174,177,113,115,175.55205133023998,114.04987618148917,0.7410860780761843,0.5362188099642642,0.16283315463615256,0.0,0.0,0.0,0.9116058349609375,0.6680416464805603,0.5046374201774597,1.445841670036316,1.9982386827468872,-0.8781152963638306,1040.8746337890625,1246.41650390625,174.00132751464844,324.0367126464844,176,114,176,114,0 -50.0,9,4,151,153,114,117,152.1871476252874,115.63028353568376,0.48095826210822,0.6356395785983309,0.07639408352264554,0.0,0.0,0.0,0.8167054653167725,0.670514702796936,1.1811758279800415,2.1196460723876953,1.6038354635238647,-0.5094975829124451,865.3943481445312,1069.474853515625,156.1915740966797,325.6314697265625,152,116,152,116,0 -50.0,5,5,163,165,115,117,163.95225483082237,116.00528093490203,0.374075066958115,0.3577939643792807,0.0002521271343505216,0.0,0.0,0.0,0.6116199493408203,0.5981555581092834,0.01548092719167471,2.6732614040374756,2.7949059009552,-0.003767541144043207,317.9984130859375,439.17156982421875,84.53144073486328,145.8155517578125,164,116,164,116,0 -50.0,7,6,98,100,117,119,98.65149939505237,118.0863467770214,0.44266055569861723,0.5593335486116389,-0.017533634566891387,0.0,0.0,0.0,0.7496075630187988,0.6633871793746948,-1.4248110055923462,2.261875867843628,1.7900645732879639,0.1418077051639557,491.198974609375,656.94287109375,83.21324157714844,165.42294311523438,98,119,98,119,0 -50.0,11,7,229,231,116,119,229.95314230049803,117.64745876073405,0.5504269975474002,0.8144101406303443,0.08519132625287562,0.0,0.0,0.0,0.9162505865097046,0.7247909903526306,1.284218430519104,1.8466689586639404,1.2480891942977905,-0.3863414227962494,1191.782958984375,1374.124267578125,198.36392211914062,425.5563049316406,230,118,230,118,0 -50.0,14,12,80,83,117,120,81.27728849785663,118.50844112419375,0.8611683175949063,0.8204189620991977,-0.06183565152176973,0.0,0.0,0.0,0.951787531375885,0.8807314038276672,-0.6262511014938354,1.1675318479537964,1.2255219221115112,0.17599566280841827,1724.521484375,1969.457275390625,218.64141845703125,353.6086730957031,81,119,81,119,0 -50.0,13,9,115,118,116,119,116.08239871767888,117.44888304512521,0.6881466473733338,0.8163655062670374,0.06376713896700692,0.0,0.0,0.0,0.9179753661155701,0.8135313987731934,1.1794356107711792,1.4637736082077026,1.2338725328445435,-0.22867369651794434,1770.3150634765625,1960.9503173828125,262.4438171386719,524.7149047851562,116,118,116,118,1 -50.0,31,22,118,124,115,120,121.28606590037047,117.83726306534672,1.181715416294793,1.1461852783493534,0.07613233445429657,0.0,0.0,0.0,1.1145079135894775,1.0420042276382446,0.6707768440246582,0.8498642444610596,0.8762088418006897,-0.11289998143911362,11445.1181640625,11592.1357421875,1504.4923095703125,3275.290771484375,121,118,121,118,1 -50.0,13,10,6,9,120,123,7.742108719480042,121.14587691215478,0.8190065048858246,0.867751017175264,0.2567172925623664,0.0,0.0,0.0,1.0494047403335571,0.7651844024658203,0.8327253460884094,1.3457887172698975,1.2701911926269531,-0.7962819337844849,1551.7139892578125,1828.21240234375,217.6048583984375,394.1180725097656,8,121,7,121,0 -50.0,10,10,67,70,121,123,68.2793984970471,121.96216562914779,0.7541473916404862,0.5319123174765144,0.007886728630120077,0.0,0.0,0.0,0.8685775399208069,0.7291315197944641,0.035428814589977264,1.3262063264846802,1.8803006410598755,-0.03932764753699303,1055.5311279296875,1299.6002197265625,169.7347412109375,293.4046936035156,68,122,68,122,0 -50.0,7,6,237,239,121,123,238.26895124072104,122.05316397101473,0.42979035108526364,0.4979544171275505,0.016395952255588764,0.0,0.0,0.0,0.7083030343055725,0.6527262926101685,1.3466004133224487,2.3296420574188232,2.010741710662842,-0.15341444313526154,624.626953125,818.4939575195312,135.58457946777344,293.4479064941406,238,122,238,122,0 -50.0,15,11,14,17,121,124,15.587998640939867,122.43250729925681,0.8102307520697134,0.8196203951765497,0.07333122139327486,0.0,0.0,0.0,0.9425534009933472,0.8610715270042419,0.8173655867576599,1.2442920207977295,1.2300373315811157,-0.22265297174453735,2823.12158203125,3034.147705078125,374.66009521484375,652.7327270507812,16,122,16,122,0 -50.0,10,7,121,124,122,124,122.59321236634327,123.20842503357795,0.7570422028615695,0.501718745751712,0.013892865758740935,0.0,0.0,0.0,0.8705147504806519,0.7077888250350952,0.05419951677322388,1.3216018676757812,1.9941619634628296,-0.07319175451993942,1036.5521240234375,1218.043212890625,173.5876922607422,331.6861572265625,123,123,123,123,0 -50.0,8,7,0,2,125,127,1.1065010883879451,125.90811946198343,0.574650086625307,0.5546549139531832,0.16842878651986304,0.0,0.0,0.0,0.8563747406005859,0.6292275190353394,0.7557539939880371,1.9102039337158203,1.9790663719177246,-1.1601207256317139,621.3777465820312,840.8668823242188,106.15147399902344,160.17347717285156,1,126,2,126,2 -50.0,18,12,28,32,109,113,29.452741180802104,110.7017230885289,0.9183332108805562,0.9952245514791924,0.08885865966379791,0.0,0.0,0.0,1.026449203491211,0.9273402094841003,0.9895689487457275,1.098418951034546,1.0135548114776611,-0.19614474475383759,3588.156982421875,3799.65087890625,452.9711608886719,880.1154174804688,29,111,29,111,1 -50.0,41,34,23,29,112,119,25.653879278422316,115.35707908616341,1.2035768322187455,1.1516790994291917,0.07031288941656655,0.0,0.0,0.0,1.1191855669021606,1.0500855445861816,0.6086267828941345,0.8338308334350586,0.8714054822921753,-0.10181491076946259,42316.421875,42555.5703125,5114.97802734375,9188.5126953125,26,115,26,115,1 -50.0,39,29,20,26,120,128,22.0155912579059,125.14276806186326,1.6359757577705878,1.619065517731542,-0.5533300667182637,0.0,0.0,0.0,1.4767922163009644,1.0364004373550415,-0.7777585387229919,0.691146969795227,0.6983656287193298,0.47241127490997314,15577.6455078125,15935.986328125,1981.87890625,3972.42626953125,22,125,22,125,1 -50.0,17,10,78,82,126,130,79.71536906238485,128.25855698231499,0.899019246115071,0.8669755986615897,0.0720716818144167,0.0,0.0,0.0,0.9781761169433594,0.8995367288589478,0.6760247349739075,1.1197857856750488,1.1611733436584473,-0.18617558479309082,3302.115234375,3534.915771484375,464.0919494628906,897.1429443359375,80,128,80,128,0 -50.0,16,10,231,234,127,130,232.5205231462355,128.5843101409907,0.856526994334935,0.8415716939626212,0.008270887078254407,0.0,0.0,0.0,0.9274693131446838,0.9153684377670288,0.41786226630210876,1.167616367340088,1.1883656978607178,-0.022950446233153343,2830.6591796875,2993.727294921875,367.00201416015625,681.531982421875,233,129,232,129,0 -50.0,15,12,249,252,128,131,250.32516507550258,129.71274897145332,0.8136371932525819,0.7925272080723351,0.05606036314231666,0.0,0.0,0.0,0.9274306297302246,0.863734245300293,0.6923479437828064,1.235068440437317,1.2679661512374878,-0.17472811043262482,3809.643310546875,4134.599609375,578.5346069335938,1260.023193359375,250,130,250,130,0 -50.0,12,6,146,149,129,132,147.51705491190415,130.44161870580453,0.7034907252482396,0.7072505855132363,0.0019366491528760577,0.0,0.0,0.0,0.8414687514305115,0.8382551074028015,1.1706671714782715,1.4214935302734375,1.4139366149902344,-0.007784890942275524,1262.6558837890625,1417.5640869140625,179.7154541015625,308.4154968261719,148,130,148,130,0 -50.0,13,10,101,104,130,133,102.35946084323645,131.37106649764092,0.7567160527035637,0.7336958362689414,0.07460948455926064,0.0,0.0,0.0,0.9059238433837891,0.818360447883606,0.7088658213615417,1.3348835706710815,1.3767664432525635,-0.2714884579181671,2307.30712890625,2568.462890625,340.8043212890625,626.9829711914062,102,131,102,131,0 -50.0,9,6,208,210,130,133,208.95033071715966,131.39163560781293,0.5030512404059267,0.6454881109641368,0.08460048697528633,0.0,0.0,0.0,0.8275601863861084,0.6809430718421936,1.1352612972259521,2.032672643661499,1.584132194519043,-0.5328218936920166,948.03515625,1184.479736328125,168.40411376953125,314.9342346191406,209,131,209,131,0 -50.0,11,7,236,239,131,134,237.6849822935845,132.45264400446746,0.6168978855012313,0.7152267486770896,0.04721366893740253,0.0,0.0,0.0,0.8568698167800903,0.7732391357421875,1.188216209411621,1.6292450428009033,1.4052575826644897,-0.2151000052690506,1159.48046875,1352.918701171875,177.21189880371094,313.060546875,238,132,238,132,0 -50.0,13,9,49,52,131,134,50.79858065504387,132.66742338147006,0.7295527265944166,0.740247599377728,0.06915431945975925,0.0,0.0,0.0,0.8968059420585632,0.815805971622467,0.8239844441413879,1.3829493522644043,1.362968921661377,-0.25839170813560486,1976.2288818359375,2187.904541015625,308.0315246582031,601.7872924804688,51,133,51,133,1 -50.0,18,11,44,48,132,136,45.7523668020241,134.3118455950063,0.9562688887338879,0.8796215952829041,0.09685324880160584,0.0,0.0,0.0,1.0109920501708984,0.9021006226539612,0.5970064401626587,1.0575244426727295,1.1496737003326416,-0.2328835129737854,3305.981201171875,3486.92236328125,467.7377624511719,940.4087524414062,46,134,46,134,1 -50.0,64,60,170,179,123,132,172.7312499689635,127.90720173270509,1.6216028788989227,1.4279164092775005,0.0894621843634269,0.0,0.0,0.0,1.2870900630950928,1.1802196502685547,0.37290042638778687,0.6188126802444458,0.7027501463890076,-0.07754002511501312,61149.91796875,61578.32421875,7527.4521484375,14499.615234375,173,128,173,128,1 -50.0,23,21,169,173,131,136,170.4632872403795,133.5842055076753,1.0144216834455415,1.3180165695337962,0.12141770335064717,0.0,0.0,0.0,1.1664484739303589,0.985817551612854,1.2334665060043335,0.9967739582061768,0.7671747803688049,-0.18364867568016052,6034.1708984375,6261.2578125,682.129150390625,1306.792236328125,170,134,170,134,1 -50.0,13,9,31,34,134,137,32.47272224078316,135.13951459420474,0.9115229840107784,0.6949146818645622,-0.0669544808125273,0.0,0.0,0.0,0.9646490812301636,0.8221251368522644,-0.2768501043319702,1.1048845052719116,1.4492824077606201,0.2129095047712326,1438.65966796875,1645.3182373046875,200.69418334960938,403.5813903808594,32,135,32,135,0 -50.0,19,13,229,233,133,137,231.2792915287763,134.91807278332283,1.4371809133881266,1.4037388671635402,0.5006025074152793,0.0,0.0,0.0,1.386124610900879,0.9589464068412781,0.7687034606933594,0.7944985032081604,0.8134262561798096,-0.5666694045066833,1635.2796630859375,1918.325439453125,137.08741760253906,284.4859924316406,232,136,232,136,0 -50.0,7,6,53,55,137,139,53.658243608617134,138.0414587240305,0.40895778010267597,0.5314508684932131,0.0010642852348787812,0.0,0.0,0.0,0.7290130853652954,0.6394908428192139,1.5621086359024048,2.4452528953552246,1.8816512823104858,-0.009793742559850216,610.3364868164062,815.694580078125,119.79959106445312,208.39627075195312,54,138,54,138,0 -50.0,10,8,190,192,136,139,190.98670602455053,137.8254050308078,0.5361929571427688,0.8212853893767602,-0.03544723565085883,0.0,0.0,0.0,0.9086400270462036,0.7292816042900085,-1.44893217086792,1.870336890220642,1.2210876941680908,0.16145002841949463,818.9918212890625,1007.0955810546875,127.84555053710938,241.55992126464844,191,138,191,138,0 -50.0,9,6,174,176,139,141,175.05542569892074,140.03131644092767,0.5572787564899573,0.5563666747001208,0.009183906799792307,0.0,0.0,0.0,0.752341628074646,0.7400185465812683,0.7605902552604675,1.7949223518371582,1.7978649139404297,-0.05925732105970383,764.5651245117188,930.8259887695312,148.8936004638672,334.71429443359375,175,140,175,140,0 -50.0,17,10,27,31,141,144,28.868943898294628,142.4073849140272,0.9193796874757236,0.7977545875602376,0.05090868577480068,0.0,0.0,0.0,0.9684398770332336,0.8827561736106873,0.3484906554222107,1.0915470123291016,1.2579635381698608,-0.13931408524513245,3505.49169921875,3708.1162109375,499.9112243652344,967.7725830078125,29,142,29,142,0 -50.0,20,10,21,25,142,146,22.934870306110593,144.0949012483565,0.9369920662733748,0.8697356612833858,0.06168415673571204,0.0,0.0,0.0,0.9867213368415833,0.912747859954834,0.5358353853225708,1.0722512006759644,1.155168056488037,-0.1520942896604538,5109.77978515625,5279.94921875,780.55517578125,1677.539794921875,23,144,23,144,0 -50.0,25,17,143,148,142,146,145.04664784112313,143.82039503999104,1.0865495486515888,0.9742173280140252,0.025175972939908142,0.0,0.0,0.0,1.0449564456939697,0.9842931032180786,0.21069523692131042,0.9208959937095642,1.0270800590515137,-0.04759605973958969,11582.1875,11821.84375,1639.66796875,3557.256591796875,145,144,145,144,0 -50.0,9,7,209,212,144,146,210.59747715009124,145.12412679830436,0.6442492760123306,0.49038006320383665,0.07588192850460773,0.0,0.0,0.0,0.8218119144439697,0.6776831746101379,0.3892548680305481,1.5810096263885498,2.0770914554595947,-0.4892942011356354,996.065673828125,1245.2906494140625,174.51806640625,328.2407531738281,211,145,210,145,0 -50.0,19,14,116,121,139,142,118.20208193600588,140.61460035067674,1.0876927306307103,0.8077432551145707,-0.008067166973891648,0.0,0.0,0.0,1.0430364608764648,0.8986161351203918,-0.02878466807305813,0.9194453954696655,1.2381088733673096,0.018365537747740746,5751.80322265625,5985.53955078125,795.7899169921875,1654.373779296875,118,141,118,141,1 -50.0,42,36,118,125,142,148,121.36214298823376,144.55561414265296,1.2657578828255254,1.1777720533294467,0.041294720081836545,0.0,0.0,0.0,1.1322996616363525,1.077695369720459,0.37688615918159485,0.7909452319145203,0.8500330448150635,-0.05546380952000618,37530.05859375,37654.81640625,4567.80322265625,9231.2744140625,121,145,121,145,1 -50.0,28,21,238,242,140,147,240.45830777758763,144.5355624589391,0.9146632050613501,1.6024027357135182,0.08173177717751123,0.0,0.0,0.0,1.2696386575698853,0.9513587951660156,1.45412015914917,1.0983043909072876,0.6269201636314392,-0.1120397076010704,12489.166015625,12981.0419921875,1691.6353759765625,3603.81494140625,240,145,240,145,1 -50.0,14,10,173,176,148,151,174.2108849176321,149.38141080929515,0.7676169464050502,0.8122232945530969,0.037660711889528686,0.0,0.0,0.0,0.913066029548645,0.8638001680374146,1.0527353286743164,1.3057034015655518,1.2339956760406494,-0.12108423560857773,2228.755126953125,2466.532470703125,330.5773010253906,626.5179443359375,174,149,174,149,0 -50.0,9,7,230,232,150,152,230.8578475178256,150.96071672323404,0.563276962223381,0.5576478412628757,0.020009959589370796,0.0,0.0,0.0,0.7620166540145874,0.7350206971168518,0.7155275344848633,1.7775914669036865,1.7955352067947388,-0.12756988406181335,841.96533203125,1039.616943359375,155.09835815429688,305.9304504394531,231,151,231,151,0 -50.0,14,12,19,22,150,153,20.28165337140498,151.55289385988917,0.7684850196109168,0.8032441180110417,0.00661752510848479,0.0,0.0,0.0,0.8969177007675171,0.8759382367134094,1.3888885974884033,1.3013538122177124,1.2450398206710815,-0.02144240215420723,2322.1748046875,2536.270263671875,337.3472595214844,702.6133422851562,20,152,20,152,0 -50.0,53,44,62,70,142,151,65.77904792011363,146.02650408390355,1.535587446629787,1.4108287997205586,0.12409687902350797,0.0,0.0,0.0,1.2696853876113892,1.155125617980957,0.5525089502334595,0.6558788418769836,0.7138777375221252,-0.11538255959749222,46392.34375,46637.58984375,5883.85595703125,12150.7998046875,66,146,66,146,1 -50.0,39,35,62,70,148,153,64.0217138785006,150.4780543892049,1.8949374530426155,1.2121691474850902,0.2901365815786825,0.0,0.0,0.0,1.4147698879241943,1.0514432191848755,0.352213054895401,0.547797441482544,0.8563506603240967,-0.2622341513633728,25510.873046875,25721.947265625,2942.019287109375,5496.11962890625,64,150,64,151,1 -50.0,23,17,89,93,149,153,90.58271591136668,150.88095685444708,1.03797213035965,1.0146685263176294,0.007653593768452094,0.0,0.0,0.0,1.0199319124221802,1.0061707496643066,0.2905910313129425,0.9634705781936646,0.9855983257293701,-0.014534820802509785,7097.419921875,7348.13427734375,908.8847045898438,1862.6878662109375,90,151,90,151,0 -50.0,13,9,34,37,149,152,35.24476883379809,150.33808382225726,0.7462112498245488,0.7544097765052116,0.09397027876806896,0.0,0.0,0.0,0.9188961386680603,0.810093104839325,0.8071958422660828,1.3614588975906372,1.3466633558273315,-0.3391702473163605,1949.6005859375,2165.385986328125,302.72967529296875,606.8054809570312,35,150,35,150,1 -50.0,16,12,112,115,152,156,113.34444326230683,154.1512402506345,0.8203582225959316,0.8756721783721897,-0.028638555666791632,0.0,0.0,0.0,0.9422463774681091,0.8990006446838379,-1.1693800687789917,1.2203730344772339,1.1432851552963257,0.07982375472784042,3507.621337890625,3766.90283203125,516.9185791015625,1087.2972412109375,113,154,113,154,0 -50.0,27,20,103,109,153,157,105.80109388625928,155.02522936148225,1.5730421214421302,1.109376859396904,0.3682605728655597,0.0,0.0,0.0,1.3328042030334473,0.9518675208091736,0.5044715404510498,0.6892762780189514,0.9773600697517395,-0.45761415362358093,8948.6005859375,9258.4453125,999.4824829101562,1856.95654296875,106,155,106,155,0 -50.0,46,38,164,171,151,158,167.47984916446734,154.11368238185443,1.7401410700710436,1.5688313036570474,-0.32842603930539127,0.0,0.0,0.0,1.4120545387268066,1.1467669010162354,-0.6578375697135925,0.5983055233955383,0.6636379361152649,0.250503808259964,19925.2890625,20361.919921875,2281.2578125,4291.72607421875,168,154,168,154,0 -50.0,15,10,120,123,159,162,121.67316299617069,160.72415444579465,0.8138794626755486,0.8011684380874149,-0.03458656821480677,0.0,0.0,0.0,0.9179812669754028,0.8788391947746277,-0.6945335268974304,1.2309414148330688,1.2504709959030151,0.1062798723578453,2777.134521484375,3001.947998046875,409.5538024902344,768.7652587890625,122,161,122,161,0 -50.0,54,43,224,233,158,164,228.1431584528784,161.00395690231196,2.070994698087972,1.3323476636060256,-0.04067378330303306,0.0,0.0,0.0,1.4398707151412964,1.153306007385254,-0.05484423041343689,0.4831494390964508,0.7510051131248474,0.029499080032110214,38784.5625,39021.8203125,4405.72412109375,8039.20751953125,228,161,228,161,1 -50.0,13,7,244,247,161,164,245.27821640967676,162.3819041303922,0.7407631056980253,0.7362402182599621,0.07570243586821035,0.0,0.0,0.0,0.9023513197898865,0.8141040802001953,0.7704662084579468,1.364295244216919,1.3726764917373657,-0.2805618941783905,1368.9432373046875,1537.29345703125,209.40750122070312,400.3498840332031,245,162,245,162,0 -50.0,11,9,36,39,162,165,37.17796157587007,163.08763106909413,0.681858442855767,0.7211644757819864,-0.022118800843989428,0.0,0.0,0.0,0.855043888092041,0.819709062576294,-1.1486165523529053,1.4680407047271729,1.3880271911621094,0.09005241096019745,1118.764404296875,1307.34521484375,180.7860107421875,390.40338134765625,37,163,37,163,0 -50.0,8,6,109,111,164,166,110.12828732280124,165.192654073312,0.5265284512827708,0.5197390957624781,-0.07004781059990339,0.0,0.0,0.0,0.7702361941337585,0.6730555295944214,-0.7611859440803528,1.9339077472686768,1.9591703414916992,0.5212846398353577,664.8943481445312,811.210693359375,127.68495178222656,265.65618896484375,110,165,110,165,0 -50.0,10,8,235,238,164,166,236.84130749255226,165.03130630053832,0.671900364710361,0.5398555403971224,0.012789214547134664,0.0,0.0,0.0,0.8204435706138611,0.7339129447937012,0.09567020833492279,1.4889873266220093,1.8531830310821533,-0.07054842263460159,1388.251953125,1646.692138671875,252.84324645996094,533.6317749023438,237,165,237,165,0 -50.0,8,7,172,174,166,168,173.3338524696255,166.73524978049198,0.5246890070945387,0.5666820296680555,0.06308346047378866,0.0,0.0,0.0,0.7824138402938843,0.692242443561554,0.9460500478744507,1.9317456483840942,1.7885968685150146,-0.4300866723060608,799.665771484375,997.4796752929688,157.57974243164062,344.883056640625,173,167,173,167,1 -50.0,5,5,38,40,167,169,39.03243863672632,167.98969756807276,0.3628741606015473,0.3554588867203696,0.00033421674430811343,0.0,0.0,0.0,0.6024028658866882,0.5961911082267761,0.044949907809495926,2.7557785511016846,2.813267230987549,-0.005182188004255295,383.4324645996094,560.9086303710938,107.55609130859375,241.1979217529297,39,168,39,168,0 -50.0,61,49,75,83,162,170,78.8096342976449,165.4129035450814,1.820969850519358,1.6320885096655768,-0.32414276236744755,0.0,0.0,0.0,1.4367148876190186,1.1785197257995605,-0.6436446309089661,0.5692837834358215,0.6351669430732727,0.22612649202346802,50400.75,50784.265625,6027.1064453125,12181.498046875,79,165,79,165,0 -50.0,9,7,133,135,168,170,133.87009880977547,168.89750763063358,0.5622101009507446,0.554513671747742,0.001627290945930393,0.0,0.0,0.0,0.7500267028808594,0.74443519115448,0.20003217458724976,1.7787095308303833,1.8033974170684814,-0.01043969951570034,961.1838989257812,1197.446533203125,176.5717010498047,342.01824951171875,134,169,134,169,0 -50.0,9,8,137,139,168,170,138.013299395913,169.06835782778074,0.5698985391511926,0.5605725553625871,0.00796246204348483,0.0,0.0,0.0,0.7579333186149597,0.745659589767456,0.5205080509185791,1.7550466060638428,1.7842445373535156,-0.04985792562365532,972.1076049804688,1182.676025390625,182.20347595214844,387.8984069824219,138,169,138,169,0 -50.0,8,6,107,109,168,171,108.06671116373461,169.4930828487435,0.4663539533042256,0.5801921282903639,0.0011076332469459604,0.0,0.0,0.0,0.761710524559021,0.6828932166099548,1.5610677003860474,2.144303798675537,1.7235747575759888,-0.00818729493767023,738.499755859375,935.7271728515625,134.5697479248047,265.2584533691406,108,169,108,170,0 -50.0,18,14,102,106,172,175,104.11505731592881,173.3129381755778,1.0836894748040669,0.8047617434278569,0.0037585170535336943,0.0,0.0,0.0,1.041028380393982,0.8970569372177124,0.013471616432070732,0.9227885007858276,1.2426239252090454,-0.008619486354291439,3471.759521484375,3688.105712890625,471.44134521484375,926.25048828125,104,173,104,173,0 -50.0,28,18,230,235,169,174,232.42232829008807,170.98815370584745,1.125285301006926,1.0402816311967342,0.05759371684789105,0.0,0.0,0.0,1.074412226676941,1.0055869817733765,0.46752285957336426,0.8911888003349304,0.9640097618103027,-0.09867880493402481,12197.7861328125,12361.3359375,1624.1441650390625,3420.303466796875,232,171,232,171,1 -50.0,37,29,172,178,172,178,174.62357044249075,175.4369740091023,1.1722705604927341,1.1142232187674548,0.08608887075116911,0.0,0.0,0.0,1.1108989715576172,1.0258641242980957,0.6228135824203491,0.8579132556915283,0.9026076793670654,-0.13257089257240295,32440.732421875,32687.998046875,3771.10205078125,6405.78076171875,175,175,175,175,0 -50.0,10,8,134,137,178,180,135.33660530334623,179.28259862430156,0.7421578910936137,0.5614873902549085,-0.011586373153229967,0.0,0.0,0.0,0.8619152307510376,0.7488306760787964,-0.06378162652254105,1.3478564023971558,1.7815577983856201,0.05562642216682434,1071.9044189453125,1220.967529296875,175.61314392089844,360.5016784667969,135,179,135,179,1 -50.0,10,7,163,165,178,181,163.99192081769817,179.7057272327167,0.5400407008081732,0.6818314403060795,-0.006578701920323615,0.0,0.0,0.0,0.8259152770042419,0.7346673607826233,-1.524531602859497,1.8519299030303955,1.4668105840682983,0.035736970603466034,1156.865478515625,1377.094970703125,198.52276611328125,392.4238586425781,164,180,164,180,0 -50.0,16,9,84,87,178,182,85.60188663401858,180.11016637816422,0.778088308443492,0.890818347883144,0.011470673157125244,0.0,0.0,0.0,0.9444435834884644,0.8814380168914795,1.4704136848449707,1.285445213317871,1.1227765083312988,-0.03310421481728554,3166.9609375,3389.04541015625,462.357666015625,907.5425415039062,86,180,86,180,0 -50.0,25,16,148,152,172,177,149.88491855304176,174.65183098903012,1.0146335375410525,1.042975807015555,0.03864124691125337,0.0,0.0,0.0,1.0343899726867676,0.9938042163848877,0.961151123046875,0.9869701266288757,0.9601497650146484,-0.07313258200883865,10425.263671875,10601.453125,1401.6328125,2783.901123046875,150,175,150,175,1 -50.0,49,39,153,159,173,182,155.77765918146235,176.49361025988705,1.22612072053494,2.0230060123991436,0.1965797431875096,0.0,0.0,0.0,1.438353419303894,1.0864005088806152,1.3416314125061035,0.8284876346588135,0.5021368265151978,-0.16101175546646118,28034.208984375,28295.607421875,3336.50341796875,6251.52294921875,156,176,156,176,1 -50.0,8,6,53,56,182,184,54.49766833826391,182.91417014686917,0.5563702368334682,0.47377092712428515,0.000925701978904403,0.0,0.0,0.0,0.7459092736244202,0.6883026361465454,0.011205263435840607,1.797370195388794,2.110731601715088,-0.007023770362138748,736.0914306640625,937.4671630859375,136.3415069580078,276.9236145019531,54,183,54,183,0 -50.0,13,8,238,241,178,182,239.09629060402892,179.9456246455787,0.768791459643662,0.7955627645988539,0.14994394919185972,0.0,0.0,0.0,0.9657729268074036,0.7947558760643005,0.8299157023429871,1.3503828048706055,1.3049414157867432,-0.5090277194976807,1604.2337646484375,1780.330322265625,259.6000061035156,574.0045166015625,239,180,239,180,1 -50.0,31,21,207,213,183,188,209.7076719273408,185.62956410382677,1.4834142965084638,1.2993922920841374,0.27626521873412724,0.0,0.0,0.0,1.2971460819244385,1.0489131212234497,0.6246489882469177,0.7019133567810059,0.8013194799423218,-0.2984691262245178,8896.9296875,9142.5791015625,899.0385131835938,1580.8880615234375,209,185,209,186,1 -50.0,10,8,13,15,186,189,13.977254820478086,187.90224647162606,0.6069602728640028,0.8063461393097366,0.18047476511379723,0.0,0.0,0.0,0.955422580242157,0.7074419260025024,1.0377373695373535,1.765017032623291,1.3285797834396362,-0.7900850772857666,876.1759643554688,1064.650146484375,144.04640197753906,293.592041015625,14,188,14,188,0 -50.0,23,19,22,26,184,189,23.844531026771104,186.00850914292343,1.1067807721428684,1.4551639939690908,-0.3644725793017485,0.0,0.0,0.0,1.2980490922927856,0.9364898800849915,-1.0083154439926147,0.9847444295883179,0.7489851117134094,0.49329468607902527,4588.32275390625,4891.42578125,567.7770385742188,1174.48095703125,24,186,24,186,0 -50.0,13,8,6,9,187,190,7.662462340101239,188.76819030495662,0.7455487581145426,0.7251055391979193,0.06963316278524356,0.0,0.0,0.0,0.8976115584373474,0.8154432773590088,0.7125225067138672,1.3534331321716309,1.3915910720825195,-0.2599451541900635,1792.1629638671875,1994.2774658203125,277.4303283691406,518.3600463867188,8,189,8,189,0 -50.0,9,7,110,112,189,191,111.00744567642741,189.94312924621306,0.5701337939559779,0.5628637060393717,0.007410288983186519,0.0,0.0,0.0,0.7581244111061096,0.747157871723175,0.5573726296424866,1.7542744874954224,1.7769330739974976,-0.04619121924042702,907.1893920898438,1094.80712890625,170.1046600341797,370.3669128417969,111,190,111,190,0 -50.0,16,10,245,249,187,191,247.06324393536883,189.16211571296196,0.8204201399337299,0.8349364285409351,0.057579859410605394,0.0,0.0,0.0,0.9411236643791199,0.8772928714752197,0.8480942249298096,1.224815845489502,1.2035211324691772,-0.16893436014652252,2686.34423828125,2931.575927734375,420.7242431640625,901.4903564453125,247,189,247,189,0 -50.0,19,12,169,173,188,192,170.82963392992187,189.7675075907136,0.921168621711145,0.9218396325216611,-0.05446697665212996,0.0,0.0,0.0,0.9879130125045776,0.9311477541923523,-0.7884780168533325,1.0893834829330444,1.0885905027389526,0.12873263657093048,3667.37353515625,3838.12939453125,520.6349487304688,1041.901123046875,171,190,171,190,0 -50.0,19,10,118,122,190,194,120.1132471973162,191.87303322481736,0.9265849042012748,0.8840211324159326,0.09566392550607183,0.0,0.0,0.0,1.001651406288147,0.8984990119934082,0.6759479641914368,1.0914257764816284,1.1439757347106934,-0.2362162470817566,3449.844482421875,3619.251953125,520.2845458984375,1151.7247314453125,120,192,120,192,0 -50.0,10,7,146,149,192,194,147.76548747496005,192.96357902282347,0.6839597314614925,0.5317585195518935,0.007536151798240853,0.0,0.0,0.0,0.8272436261177063,0.7289624810218811,0.04935348778963089,1.4623026847839355,1.8808465003967285,-0.04144789278507233,1197.6107177734375,1439.3785400390625,213.1871337890625,421.04901123046875,148,193,148,193,0 -50.0,18,13,45,49,193,196,46.92533387478167,194.5120641543204,1.0036087729122185,0.8268242836182682,0.1199976358049537,0.0,0.0,0.0,1.0316276550292969,0.8753156661987305,0.46795788407325745,1.0139998197555542,1.230804681777954,-0.2943251430988312,4635.35693359375,4917.32080078125,611.3490600585938,1093.5638427734375,47,195,47,194,0 -50.0,12,7,64,67,194,197,65.58971144878504,195.44489062648682,0.6951095138639896,0.6971744264145294,0.0024656071818163205,0.0,0.0,0.0,0.835951566696167,0.8327478170394897,0.9836777448654175,1.4386402368545532,1.43437922000885,-0.010175708681344986,1393.166259765625,1578.1617431640625,207.43226623535156,366.4150695800781,66,195,66,195,0 -50.0,12,9,93,97,194,197,94.95957630935838,195.14934529276948,0.7662445310559898,0.6383636645738275,0.011897637478371248,0.0,0.0,0.0,0.8759806156158447,0.7982895374298096,0.09198489785194397,1.3054442405700684,1.5669586658477783,-0.04866098240017891,1768.6051025390625,2060.195556640625,294.3650817871094,596.2394409179688,95,195,95,195,0 -50.0,7,5,130,132,195,197,131.29204430500243,196.04746816144342,0.417532833003885,0.49298802892577465,0.011087601370090017,0.0,0.0,0.0,0.7032663226127625,0.6449320316314697,1.4278773069381714,2.3964524269104004,2.0296590328216553,-0.1077953577041626,527.693359375,700.2392578125,116.58820343017578,256.6246337890625,131,196,131,196,0 -50.0,8,6,203,205,197,199,203.85045671146077,197.82752000767817,0.5225681130283782,0.5096518794015312,-0.07372624675494588,0.0,0.0,0.0,0.7681917548179626,0.6649070978164673,-0.7417117357254028,1.9534956216812134,2.0030035972595215,0.5651853680610657,692.8492431640625,889.14794921875,137.24790954589844,276.852294921875,204,198,204,198,0 -50.0,7,7,20,22,198,200,20.97181726846821,198.712581731077,0.4989598824112196,0.42055135233328245,0.00808427241243126,0.0,0.0,0.0,0.7069545388221741,0.6478630304336548,0.10167928040027618,2.004793643951416,2.3785717487335205,-0.07707642763853073,708.4424438476562,963.2860717773438,155.56942749023438,336.6973571777344,21,199,21,199,0 -50.0,9,8,34,37,198,200,35.68024908250566,198.85036701358948,0.7771364368129703,0.49572395814090586,-0.1413694446691316,0.0,0.0,0.0,0.9142693281173706,0.6610385775566101,-0.3938746452331543,1.3571816682815552,2.127626419067383,0.7740760445594788,625.6058959960938,815.6748657226562,95.4135971069336,183.80078125,35,199,35,199,0 -50.0,6,5,76,78,198,200,77.16032800584777,199.16656581860843,0.4134247957357624,0.4154434365722537,0.0995802845131386,0.0,0.0,0.0,0.7169515490531921,0.5611138343811035,0.7904658913612366,2.5670266151428223,2.554553508758545,-1.2306139469146729,436.48895263671875,614.0065307617188,106.48932647705078,223.17417907714844,77,199,77,199,0 -50.0,26,21,102,106,190,195,103.83860659703853,192.31668225006476,1.0347149854278692,1.1286113822326396,0.003179681610970597,0.0,0.0,0.0,1.062411904335022,1.0171566009521484,1.5369842052459717,0.9664580821990967,0.8860522508621216,-0.0054456815123558044,10189.072265625,10399.9580078125,1350.5528564453125,2729.5087890625,104,192,104,192,1 -50.0,37,29,162,169,194,199,165.4424951274909,196.47706679388173,1.3194297196430718,1.1577458295528604,0.0961145964438046,0.0,0.0,0.0,1.1679812669754028,1.0549860000610352,0.43574607372283936,0.7625145316123962,0.8690027594566345,-0.12660598754882812,20395.8828125,20578.71484375,2266.77880859375,4243.14306640625,165,197,165,197,1 -50.0,17,11,167,171,200,204,169.50463651650068,201.80886078624664,1.156225624179724,0.9802566433841386,-0.16489108213208947,0.0,0.0,0.0,1.1203292608261108,0.9387995004653931,-0.5403189659118652,0.8861407041549683,1.0452146530151367,0.29811927676200867,2213.773193359375,2427.66552734375,293.0205078125,562.4413452148438,170,202,170,202,1 -50.0,17,12,209,213,200,204,210.74718321925297,201.52421492955463,0.9883306113631671,0.9643577173986144,0.25375910067420104,0.0,0.0,0.0,1.1092277765274048,0.8498836159706116,0.7617979645729065,1.0851200819015503,1.1120949983596802,-0.571072518825531,2930.833740234375,3161.617919921875,374.044921875,661.885986328125,211,201,211,201,0 -50.0,15,12,99,102,203,206,100.37743842772258,204.64735332326086,0.8418103052613364,0.8128765850903301,0.05890615432986879,0.0,0.0,0.0,0.9423375725746155,0.8756065368652344,0.6649854779243469,1.1939705610275269,1.236469030380249,-0.17304524779319763,3225.485107421875,3480.472900390625,453.42376708984375,934.9431762695312,100,205,100,205,0 -50.0,47,37,174,185,199,206,180.09399883565362,202.73057705921056,4.386362612997615,3.4078371184790264,-0.9005334234265376,0.0,0.0,0.0,2.2185490131378174,1.6947683095932007,-0.5365545749664307,0.24105717241764069,0.31027427315711975,0.1274004876613617,5245.8369140625,5881.79345703125,311.1497802734375,610.1527099609375,179,203,179,203,0 -50.0,10,6,2,4,204,207,2.8423014912735853,205.49920194250626,0.5098348592293299,0.7249032582469233,0.012080575428520035,0.0,0.0,0.0,0.8518096804618835,0.7135533690452576,1.5148600339889526,1.9621943235397339,1.3800393342971802,-0.06540027260780334,1066.4417724609375,1297.8345947265625,178.5884246826172,329.89453125,3,206,3,206,0 -50.0,9,6,128,130,202,205,129.31077986982754,203.30928328442718,0.5457077985041376,0.7021018952314106,-0.11906638008709369,0.0,0.0,0.0,0.875416100025177,0.6938705444335938,-1.0759516954421997,1.9028921127319336,1.4790204763412476,0.6454062461853027,908.3765869140625,1036.0950927734375,155.37940979003906,316.6443786621094,129,203,129,203,1 -50.0,23,18,123,128,203,207,125.34954641683065,204.86127320355237,1.3763737813556602,1.046362434650593,0.33972256962670233,0.0,0.0,0.0,1.2605724334716797,0.9130680561065674,0.5593241453170776,0.7898420095443726,1.0389496088027954,-0.5128760933876038,5015.9287109375,5279.74609375,617.3361206054688,1301.9921875,125,205,125,205,1 -50.0,18,13,215,219,205,208,216.99632455176985,206.48172236230027,0.9570929846510539,0.8174704512073983,0.08701720578570482,0.0,0.0,0.0,0.9994206428527832,0.8807507157325745,0.44733646512031555,1.0550411939620972,1.2352404594421387,-0.22461175918579102,5112.283203125,5398.115234375,700.4776000976562,1308.5960693359375,217,206,217,207,0 -50.0,7,7,187,189,208,210,187.6913902645183,208.96844714151388,0.44158564874622086,0.4988188414668009,-0.006074122438642693,0.0,0.0,0.0,0.7067222595214844,0.6640392541885376,-1.4662190675735474,2.2649457454681396,2.0050716400146484,0.055160537362098694,528.2486572265625,695.0411376953125,106.4461441040039,187.53126525878906,188,209,188,209,0 -50.0,7,6,77,79,209,211,77.93086582638861,209.63586539284984,0.5154008270801811,0.39983544559211565,0.012476469473896579,0.0,0.0,0.0,0.718841016292572,0.6312716007232666,0.10632792860269547,1.9417041540145874,2.5029194355010986,-0.12117791175842285,684.9122924804688,929.03515625,138.81443786621094,265.839111328125,78,210,78,210,0 -50.0,17,9,107,110,207,211,108.37142276720242,208.94446954935268,0.8156804758909182,0.9155231567253881,0.06967830518844975,0.0,0.0,0.0,0.9753551483154297,0.8831115365028381,1.0962402820587158,1.2339929342269897,1.099419355392456,-0.18783257901668549,2717.74853515625,2877.212890625,399.7806091308594,859.22607421875,108,209,108,209,0 -50.0,7,6,235,237,209,211,235.737092821125,209.93627114853447,0.4362335056114959,0.49402950320172323,0.014563544853941623,0.0,0.0,0.0,0.705331027507782,0.6578534841537476,1.3373894691467285,2.2946085929870605,2.0261647701263428,-0.13528598845005035,566.5587768554688,750.4598388671875,122.14055633544922,256.31329345703125,236,210,236,210,0 -50.0,18,14,36,40,202,206,38.04184944360615,203.89501008765674,0.9532765539249439,0.9606466303114498,0.07569876626827288,0.0,0.0,0.0,1.0162431001663208,0.9387082457542419,0.8097190856933594,1.0556190013885498,1.0475202798843384,-0.1663651317358017,3635.07275390625,3777.483154296875,507.7425231933594,1087.8681640625,38,204,38,204,1 -50.0,9,8,229,231,210,212,229.8879854537433,210.92604751649353,0.561465478238664,0.560860643954427,-0.004351965114414824,0.0,0.0,0.0,0.7520142793655396,0.7461907267570496,-0.750709056854248,1.7811604738235474,1.783081293106079,0.027641620486974716,1149.0947265625,1431.982421875,212.82321166992188,420.78765869140625,230,211,230,211,0 -50.0,9,8,251,253,211,213,252.00592070720697,212.0862928920051,0.5683982597712218,0.5645819369940597,0.008887562733056686,0.0,0.0,0.0,0.7586700320243835,0.7465922832489014,0.6796533465385437,1.7597630023956299,1.771658182144165,-0.05540383979678154,1094.120361328125,1326.4547119140625,202.91714477539062,424.7433776855469,252,212,252,212,0 -50.0,19,14,87,91,212,215,88.93203485799832,213.3829683095306,1.0311215679274879,0.8300454980674701,-0.01920981835656077,0.0,0.0,0.0,1.0163366794586182,0.9100696444511414,-0.09439730644226074,0.97023606300354,1.205272912979126,0.04490852355957031,4929.39892578125,5141.37109375,684.5481567382812,1345.0286865234375,89,213,89,213,0 -50.0,14,7,108,111,215,218,109.5061713653598,216.13498744964505,0.8158372223361967,0.7800233350644412,0.009435678887437682,0.0,0.0,0.0,0.9045280814170837,0.8818670511245728,0.24247880280017853,1.225906252861023,1.282192349433899,-0.02965874783694744,1522.577392578125,1652.5638427734375,218.5478973388672,448.83160400390625,109,216,109,216,0 -50.0,18,15,119,123,208,213,121.31814662497212,211.67713569906408,0.8675811743769426,1.3376170381187364,0.27665999596519075,0.0,0.0,0.0,1.2106223106384277,0.8599953055381775,1.1374950408935547,1.2340202331542969,0.8003880977630615,-0.5104660391807556,3576.272705078125,3935.6162109375,474.7331848144531,974.9261474609375,121,212,121,212,1 -50.0,21,13,122,126,210,218,123.93590927390888,215.77581181423375,0.9716807970270329,1.4473017729312119,0.17308127310729127,0.0,0.0,0.0,1.2262213230133057,0.9567464590072632,1.256221890449524,1.051544427871704,0.705979585647583,-0.25150614976882935,4402.21923828125,4465.35107421875,605.7803955078125,1222.578857421875,124,216,124,216,1 -50.0,5,5,186,188,217,219,186.98830530041525,218.03375156105358,0.364678061452702,0.3528958710984311,0.00039470377141226365,0.0,0.0,0.0,0.6038967370986938,0.594039261341095,0.033450040966272354,2.742147922515869,2.83370041847229,-0.006134025752544403,360.0256652832031,534.266845703125,101.22126007080078,217.47390747070312,187,218,187,218,0 -50.0,24,16,92,97,215,220,94.76944579505444,216.67767290536037,1.1190694536810515,1.2093676062957721,-0.24357697887345786,0.0,0.0,0.0,1.1882526874542236,0.9573361277580261,-0.8770374059677124,0.9345698356628418,0.8647896647453308,0.3764607310295105,5753.54296875,6023.30517578125,737.0213623046875,1388.4727783203125,95,217,95,217,0 -50.0,7,6,23,25,219,221,23.70139397376081,219.9231059512344,0.42908190736209084,0.5010011554207103,0.009633421202889902,0.0,0.0,0.0,0.7087095379829407,0.6540748476982117,1.4399217367172241,2.331563949584961,1.9968653917312622,-0.08966421335935593,503.3043212890625,677.0536499023438,104.00814819335938,183.89456176757812,24,220,24,220,0 -50.0,5,5,235,237,219,221,236.04511944153757,219.99437357885455,0.3571116810488464,0.3595812407866005,0.00025381910764976645,0.0,0.0,0.0,0.5996724367141724,0.5975666046142578,1.4694292545318604,2.800245761871338,2.7810142040252686,-0.0039532422088086605,364.41259765625,531.476806640625,102.48725891113281,234.390869140625,236,220,236,220,0 -50.0,10,7,157,159,219,222,158.03794846891722,220.74862404913054,0.5388022048621726,0.6867761886761117,0.0013722011001284784,0.0,0.0,0.0,0.8287273049354553,0.7340227961540222,1.5615241527557373,1.8559781312942505,1.4560858011245728,-0.007416608743369579,1251.9862060546875,1464.2135009765625,218.1424560546875,461.557861328125,158,221,158,221,0 -50.0,11,8,1,4,220,223,2.0608816316578347,221.8113364324032,0.6501686553833439,0.6641137017181498,0.010531728767813497,0.0,0.0,0.0,0.8183959126472473,0.8028141260147095,1.077797770500183,1.5384576320648193,1.5061531066894531,-0.048794712871313095,1589.0184326171875,1862.769775390625,273.43707275390625,576.90576171875,2,222,2,222,0 -50.0,16,14,121,125,220,223,123.2190685141968,221.3456978660573,0.9002022315928189,0.8101549965518928,-0.024089863087606744,0.0,0.0,0.0,0.9519672989845276,0.8967248201370239,-0.24564623832702637,1.1117461919784546,1.2353147268295288,0.06611528247594833,3352.041259765625,3616.23583984375,477.7425231933594,929.5872802734375,123,221,123,221,0 -50.0,14,13,115,118,220,223,116.08433850389007,221.31372075578983,0.7986368383831919,0.9249363942694893,0.03354319517270854,0.0,0.0,0.0,0.9660704731941223,0.8889775276184082,1.3266609907150269,1.254043698310852,1.0828046798706055,-0.09095681458711624,2446.850341796875,2681.072509765625,334.3839416503906,667.6024169921875,116,221,116,221,1 -50.0,14,11,116,120,223,226,118.09183153601568,224.6777438743523,0.8895294957006943,0.7499072500155206,-0.009603647091158685,0.0,0.0,0.0,0.9434971809387207,0.8655921816825867,-0.0683540403842926,1.124345302581787,1.333682656288147,0.028797734528779984,2255.13916015625,2420.30419921875,329.2344970703125,693.6351928710938,118,225,118,225,1 -50.0,17,12,110,114,221,224,111.53471070731155,222.48112650209626,1.1008266670589029,0.8409921786006578,0.09585169279027106,0.0,0.0,0.0,1.0641236305236816,0.8996997475624084,0.3178205192089081,0.9175136685371399,1.2009904384613037,-0.2091463953256607,2398.96484375,2517.473388671875,282.7868347167969,492.7254638671875,111,222,111,222,1 -50.0,6,5,149,151,224,226,149.82673472249704,225.1884536735167,0.4169200138251907,0.4139284682997988,-0.103266508760958,0.0,0.0,0.0,0.7202094197273254,0.5587010979652405,-0.7781563997268677,2.5565171241760254,2.57499361038208,1.2755951881408691,479.5184020996094,666.97412109375,114.86138153076172,242.0882110595703,150,225,150,225,0 -50.0,16,12,248,252,223,226,250.08210743299975,224.53290640257526,0.8808843737619219,0.791459757453794,0.019282922349971532,0.0,0.0,0.0,0.940672755241394,0.8874000906944275,0.203583225607872,1.1358284950256348,1.264162302017212,-0.05534607172012329,3162.711669921875,3398.447998046875,448.3588562011719,898.730224609375,250,225,250,225,0 -50.0,38,29,134,141,221,227,137.8493782581361,224.56576749593108,2.304821849364096,2.4695828949209666,-0.41917727400374005,0.0,0.0,0.0,1.6776167154312134,1.400002360343933,-0.8824261426925659,0.44769322872161865,0.4178248643875122,0.15197937190532684,6999.45458984375,7414.41259765625,540.56689453125,1073.8831787109375,137,226,137,226,0 -50.0,16,10,194,197,221,225,195.52631465746572,223.41496519336698,0.8141448550276555,1.0157384990511158,-0.049429166234723265,0.0,0.0,0.0,1.0135116577148438,0.8959227204322815,-1.3428336381912231,1.2319223880767822,0.9874227046966553,0.11989876627922058,3131.047119140625,3207.652587890625,435.3096618652344,841.1790771484375,196,223,196,223,1 -50.0,14,12,191,195,224,227,192.9984326688387,225.7347421145406,0.8178106919374635,0.7408906201260681,0.0987216368723316,0.0,0.0,0.0,0.9409034848213196,0.8206107020378113,0.5996521711349487,1.2427666187286377,1.371791958808899,-0.33119046688079834,2959.78369140625,3264.645751953125,457.6318664550781,945.8510131835938,193,226,193,226,1 -50.0,19,12,25,29,226,230,27.166967997322946,227.86313763215313,0.9169645126142498,0.8989567893549082,0.07579404726843375,0.0,0.0,0.0,0.9921126961708069,0.9119395017623901,0.7262783050537109,1.0982083082199097,1.12020742893219,-0.1851872205734253,3844.523193359375,4026.031005859375,571.4877319335938,1257.9232177734375,27,228,27,228,0 -50.0,8,5,69,71,228,230,70.19890350569918,228.85066986403592,0.5005220500781111,0.5203093874814447,0.0713106169131359,0.0,0.0,0.0,0.7631574869155884,0.6621344685554504,0.8543283939361572,2.037703037261963,1.9602093696594238,-0.5585517883300781,679.53662109375,867.165283203125,135.61866760253906,295.09661865234375,70,229,70,229,0 -50.0,8,7,183,185,229,231,183.87824723850068,230.1316248963854,0.5177105824308811,0.5120823428696526,0.08825015404519554,0.0,0.0,0.0,0.7766540050506592,0.6531473398208618,0.7694595456123352,1.9900422096252441,2.0119144916534424,-0.6859112977981567,781.0192260742188,1014.4599609375,161.60757446289062,352.9825134277344,184,230,184,230,0 -50.0,15,11,113,116,228,232,114.58026027032808,229.52956865647045,0.8184332158082257,1.1073626973374897,-0.28202540769131756,0.0,0.0,0.0,1.1312695741653442,0.8037568926811218,-1.0220940113067627,1.3393938541412354,0.9899235367774963,0.6822391152381897,1798.3609619140625,2045.6446533203125,227.6949462890625,432.59149169921875,115,229,115,229,0 -50.0,7,5,137,139,230,232,138.30429752581608,231.03459982239454,0.4150631178063333,0.5011951234325192,0.00932093845698656,0.0,0.0,0.0,0.7086552381515503,0.643479585647583,1.4642232656478882,2.410278797149658,1.99606454372406,-0.08964995294809341,668.8230590820312,887.0161743164062,144.92941284179688,316.0007019042969,138,231,138,231,0 -50.0,7,5,57,59,231,233,57.625134898102054,232.10816486710578,0.40250655639167,0.5050038474663094,-0.01280156650457065,0.0,0.0,0.0,0.7117432951927185,0.6331918239593506,-1.448404312133789,2.486436128616333,1.9817806482315063,0.12605954706668854,619.5223388671875,849.4619750976562,124.21023559570312,230.5819091796875,58,232,57,232,0 -50.0,8,6,126,128,233,235,127.17022181919015,233.7534461830642,0.5260832900265129,0.507592527660426,0.08166362347788092,0.0,0.0,0.0,0.7739658951759338,0.6592819094657898,0.7290316820144653,1.9495271444320679,2.020545244216919,-0.6272962689399719,677.9461669921875,870.1986694335938,126.92463684082031,258.5210876464844,127,234,127,234,0 -50.0,14,10,171,174,232,235,172.15089422661273,233.44742402453656,0.7452648768081462,0.7917773138043902,0.01641968059641008,0.0,0.0,0.0,0.8927427530288696,0.8602630496025085,1.2634142637252808,1.3424181938171387,1.2635587453842163,-0.055677466094493866,2248.9560546875,2490.49853515625,336.2257995605469,639.6367797851562,172,233,172,233,0 -50.0,14,8,155,158,234,237,156.4896845961849,235.81470800564995,0.8109529532876971,0.7332669897451347,0.016528153409542945,0.0,0.0,0.0,0.9023985862731934,0.8543399572372437,0.20115210115909576,1.2336839437484741,1.3643865585327148,-0.05561553314328194,2215.34521484375,2411.030517578125,325.1435241699219,674.0584106445312,156,236,156,236,0 -50.0,11,8,59,62,237,240,60.802586606503986,238.1620685933368,0.6653505057115248,0.6410287043149421,0.023089168174923902,0.0,0.0,0.0,0.8241878151893616,0.7918924689292908,0.5430115461349487,1.5048482418060303,1.561944842338562,-0.10840604454278946,1565.4306640625,1826.7584228515625,264.9862365722656,522.4476318359375,61,238,61,238,0 -50.0,28,22,229,235,235,240,231.51689951206424,237.79046057772672,1.999926207253866,1.5249056120790412,-0.042554852606799365,0.0,0.0,0.0,1.4155241250991821,1.2333383560180664,-0.08864470571279526,0.5003155469894409,0.6561679244041443,0.027924159541726112,4010.712890625,4389.32763671875,389.37713623046875,723.3854370117188,231,238,231,238,0 -50.0,10,9,83,86,239,241,84.22023194856531,240.03264988865502,0.7016494055342692,0.5449910767765991,0.025009747405588145,0.0,0.0,0.0,0.8399673700332642,0.7355917692184448,0.15452954173088074,1.4275482892990112,1.8378987312316895,-0.1310209482908249,1311.204833984375,1571.4964599609375,225.06471252441406,444.26812744140625,84,240,84,240,0 -50.0,55,53,213,220,233,240,216.0897998150991,236.06806384638128,1.4715939226749555,1.4307599080063014,0.025955533109621953,0.0,0.0,0.0,1.2182775735855103,1.1908625364303589,0.45213526487350464,0.679752767086029,0.6991530060768127,-0.02466290257871151,43144.91015625,43454.30078125,5537.0,11964.8828125,216,236,216,236,1 -50.0,17,12,210,214,238,242,211.7459157022096,240.23467839494194,1.0108392794226582,0.9178708047584578,-0.05709480769604669,0.0,0.0,0.0,1.018812894821167,0.9437850713729858,-0.44374072551727295,0.992764949798584,1.0933191776275635,0.12350697815418243,2413.37451171875,2564.8369140625,289.9653015136719,459.0371398925781,212,240,211,240,1 -50.0,13,9,161,164,241,244,162.58724001080668,242.31700760664035,0.729830820171538,0.8189862387071514,-0.0677657489504182,0.0,0.0,0.0,0.9249442219734192,0.8326435089111328,-1.0763248205184937,1.3807889223098755,1.2304753065109253,0.22850248217582703,1435.24853515625,1624.6839599609375,198.88616943359375,377.7503662109375,163,242,162,242,0 -50.0,99,84,94,106,233,246,97.34318956966689,238.67362310012004,2.124187215098873,1.8483084183177922,0.08521482647350709,0.0,0.0,0.0,1.4657374620437622,1.3505959510803223,0.2766916751861572,0.47164061665534973,0.5420377850532532,-0.0434892512857914,86868.5546875,87458.7109375,10292.7255859375,20901.150390625,97,239,97,239,0 -50.0,14,10,5,8,245,248,6.542637157229798,246.6284203145519,0.9974486335233337,0.8114832975333122,0.24975671677157907,0.0,0.0,0.0,1.08211350440979,0.798725426197052,0.6072005033493042,1.0862728357315063,1.335210919380188,-0.6686618328094482,1518.14111328125,1767.45166015625,187.84912109375,340.2732849121094,7,247,7,247,0 -50.0,17,12,39,44,241,247,42.171837551088515,242.9231127154354,1.1285225551667146,1.7839364031369502,-0.07255201582094095,0.0,0.0,0.0,1.3386080265045166,1.0585780143737793,-1.4618570804595947,0.8884372711181641,0.5620275735855103,0.07226481288671494,1904.1219482421875,2041.06884765625,242.6620330810547,517.0990600585938,42,243,42,243,1 -50.0,26,19,51,56,245,249,53.081055242915035,246.83458184669124,1.1046653674772458,0.9872015908269391,0.04647861999653147,0.0,0.0,0.0,1.058693289756775,0.9854113459587097,0.33472809195518494,0.9070483446121216,1.0149749517440796,-0.08540982007980347,13176.626953125,13418.7998046875,1858.9832763671875,4043.844970703125,53,247,53,247,0 -50.0,15,10,205,209,243,246,206.3581810987629,244.16581464618176,1.012972031089145,0.8355610219446938,0.1783307735886679,0.0,0.0,0.0,1.0599250793457031,0.8515232801437378,0.5546069741249084,1.0257340669631958,1.2435237169265747,-0.4378374516963959,2035.9794921875,2200.58837890625,293.7651062011719,608.0301513671875,206,244,206,244,1 -50.0,9,6,209,211,246,249,209.8849801323291,247.62143048124497,0.4996347997058559,0.6414206568452725,-0.07670366268564277,0.0,0.0,0.0,0.8215687274932861,0.6827007532119751,-1.1584229469299316,2.0388927459716797,1.5881961584091187,0.48763802647590637,903.0819702148438,1109.634033203125,153.89529418945312,275.18450927734375,210,248,210,248,1 -50.0,16,10,104,107,246,250,105.31657273407438,247.8131884139309,0.8049937807227023,0.8387709403550865,0.03456491428696129,0.0,0.0,0.0,0.9275519251823425,0.8851057291030884,1.0126430988311768,1.2444475889205933,1.1943339109420776,-0.10256488621234894,3523.026611328125,3804.042724609375,539.486328125,1184.3157958984375,105,248,105,248,0 -50.0,19,14,135,139,242,245,136.97871664415445,243.4859554068856,0.9928296881050214,0.8405287574972586,0.06108578242266738,0.0,0.0,0.0,1.007125973701477,0.9050168991088867,0.3380320072174072,1.0117461681365967,1.1950711011886597,-0.1470581591129303,5281.9462890625,5526.6728515625,709.630615234375,1316.1962890625,137,243,137,244,1 -50.0,34,26,81,87,246,251,83.4109873725705,248.67787110245223,1.1598808865763202,1.0683060488497205,0.0721596678532217,0.0,0.0,0.0,1.0952415466308594,1.0142154693603516,0.5026869177818298,0.8657957911491394,0.9400115013122559,-0.11696186661720276,33113.62890625,33392.4453125,4274.18212890625,8921.5654296875,83,249,83,249,0 -50.0,34,25,58,63,243,249,59.895339677889254,245.8813553023165,1.181376646721163,1.1474636792445914,0.02532331086483275,0.0,0.0,0.0,1.0931130647659302,1.0648680925369263,0.4903829097747803,0.8468707203865051,0.8718997240066528,-0.037379082292318344,19783.220703125,19996.228515625,2650.31396484375,5416.69287109375,60,246,60,246,1 -50.0,27,14,183,188,247,252,185.16894806162406,249.62081395585363,1.0629610085201149,1.0070386741217252,0.048136932381370734,0.0,0.0,0.0,1.0443507432937622,0.9896116852760315,0.5222819447517395,0.9428091645240784,0.9951647520065308,-0.09013345837593079,10156.9189453125,10319.859375,1375.2359619140625,2901.402587890625,185,250,185,250,0 -50.0,20,14,197,201,248,252,198.59883151390588,250.33798427660543,0.9529339481432468,0.9385422687909415,0.04702593407868694,0.0,0.0,0.0,0.9966500997543335,0.9477155804634094,0.7094777822494507,1.0519918203353882,1.0681232213974,-0.10542071610689163,5677.8544921875,5896.82275390625,713.5069580078125,1236.096435546875,199,250,198,250,0 -50.0,9,8,237,239,252,254,237.92885995955945,253.03913680565185,0.5580391898977438,0.5593314477204272,0.007957187788520725,0.0,0.0,0.0,0.7527740001678467,0.7420929670333862,0.8259096145629883,1.7923524379730225,1.788211464881897,-0.05099689960479736,1069.4586181640625,1323.54052734375,205.17259216308594,441.3061828613281,238,253,238,253,0 -50.0,38,33,7,14,251,255,9.927606393188437,254.01407918907503,1.3872774092016922,0.7997698484130122,0.022181281353679694,0.0,0.0,0.0,1.1781823635101318,0.8938308358192444,0.03768337517976761,0.7211561799049377,1.250914454460144,-0.04000192880630493,45133.08984375,49781.29296875,6533.01123046875,12605.7646484375,10,254,10,254,2 -50.0,11,9,78,81,252,255,79.76497441964577,253.60896824328944,0.8833927987970647,0.6048077155776692,-0.07477058023791017,0.0,0.0,0.0,0.9498379826545715,0.7655118107795715,-0.24632158875465393,1.1439695358276367,1.670902132987976,0.28285109996795654,1083.3448486328125,1221.147216796875,159.8643341064453,288.6414794921875,80,254,80,254,1 -50.0,75,68,152,162,246,254,156.83950336437016,249.40614564012077,1.5839533740601581,1.4513774358883929,0.021753585363004646,0.0,0.0,0.0,1.2599331140518188,1.20328688621521,0.15854725241661072,0.6314616799354553,0.6891425251960754,-0.01892899163067341,88377.84375,88627.3203125,10209.625,18600.205078125,157,249,157,249,1 -50.0,31,22,146,152,250,255,148.9982261053605,252.4084683918445,1.27021882456852,1.1641813060311499,0.18507185386585334,0.0,0.0,0.0,1.1873148679733276,1.0122666358947754,0.6458960175514221,0.8059331774711609,0.8793402910232544,-0.256241112947464,11279.322265625,11499.77734375,1353.7044677734375,2571.017822265625,149,253,149,253,3 -50.0,45,37,165,173,249,255,168.06096267922428,252.43090248103192,1.5289350153765877,1.227638326434196,0.24465447858228018,0.0,0.0,0.0,1.2905824184417725,1.0444952249526978,0.509434700012207,0.6755943894386292,0.8414040803909302,-0.2692766785621643,34270.55078125,34649.171875,4025.617431640625,7999.544921875,168,253,168,253,2 -50.0,16,12,201,205,251,255,203.0546221825006,253.95764872289612,1.1286418905923146,1.1822129967828001,-0.32912011270131547,0.0,0.0,0.0,1.2188665866851807,0.9084157347679138,-0.8260013461112976,0.9643042683601379,0.9206075668334961,0.5369116067886353,1832.5498046875,2213.87060546875,253.676513671875,460.0503234863281,203,254,203,254,2 diff --git a/development/testC0/tess/tess_fit_zp.png b/development/testC0/tess/tess_fit_zp.png new file mode 100755 index 0000000..863747d Binary files /dev/null and b/development/testC0/tess/tess_fit_zp.png differ diff --git a/development/testC0/tess/tess_fit_zp_residual.png b/development/testC0/tess/tess_fit_zp_residual.png new file mode 100755 index 0000000..e291534 Binary files /dev/null and b/development/testC0/tess/tess_fit_zp_residual.png differ diff --git a/development/test_SLR.pdf b/development/test_SLR.pdf new file mode 100755 index 0000000..41c7b43 Binary files /dev/null and b/development/test_SLR.pdf differ diff --git a/development/test_diff_diag.pdf b/development/test_diff_diag.pdf new file mode 100755 index 0000000..90c5557 Binary files /dev/null and b/development/test_diff_diag.pdf differ diff --git a/development/test_disp.pdf b/development/test_disp.pdf new file mode 100755 index 0000000..3ed6c80 Binary files /dev/null and b/development/test_disp.pdf differ diff --git a/development/testcal_sources.pdf b/development/testcal_sources.pdf new file mode 100755 index 0000000..0d8b985 Binary files /dev/null and b/development/testcal_sources.pdf differ diff --git a/development/testcal_zp.pdf b/development/testcal_zp.pdf new file mode 100755 index 0000000..d88252e Binary files /dev/null and b/development/testcal_zp.pdf differ diff --git a/development/testref.csv b/development/testref.csv deleted file mode 100644 index e14ec74..0000000 --- a/development/testref.csv +++ /dev/null @@ -1,277 +0,0 @@ -thresh,npix,tnpix,xmin,xmax,ymin,ymax,x,y,x2,y2,xy,errx2,erry2,errxy,a,b,theta,cxx,cyy,cxy,cflux,flux,cpeak,peak,xcpeak,ycpeak,xpeak,ypeak,flag -50.0,8,5,139,142,0,2,140.46665810675026,0.9885802268972921,0.6974033225347434,0.4442712114955433,-0.002791812280867889,0.0,0.0,0.0,0.835125207901001,0.6665136218070984,-0.01102728396654129,1.4339265823364258,2.250933885574341,0.01802166737616062,516.6826171875,648.6361694335938,86.78633880615234,153.4512481689453,140,1,141,1,2 -50.0,16,9,130,134,0,3,131.95947394974425,1.4884902976833962,0.8901497417307289,0.7799589450249829,0.010273654545700062,0.0,0.0,0.0,0.9439806342124939,0.8826150298118591,0.09217651188373566,1.123577356338501,1.2823137044906616,-0.029599621891975403,2568.425537109375,2750.826416015625,359.0827941894531,665.7167358398438,132,1,132,1,2 -50.0,14,8,167,170,0,3,168.67912210582574,1.103459153750733,0.7967220340009602,0.7030207714594441,0.010116508024078374,0.0,0.0,0.0,0.8931975364685059,0.8378191590309143,0.10633297264575958,1.2553722858428955,1.4226930141448975,-0.03612975403666496,2583.957763671875,2853.582275390625,419.1460876464844,866.5338745117188,169,1,169,1,2 -50.0,18,11,175,179,0,3,176.91508942388583,0.9347407455188642,1.0017826942242043,0.6675093419280639,0.007109035992796331,0.0,0.0,0.0,1.0009664297103882,0.8169199824333191,0.021254321560263634,0.9982959032058716,1.498219609260559,-0.021263888105750084,6612.13671875,7324.49365234375,1047.0023193359375,2139.08740234375,177,1,177,1,2 -50.0,14,10,79,82,1,4,80.78529208785861,2.49267326472605,0.7644665225503728,0.83669786915778,-0.008500683295045164,0.0,0.0,0.0,0.9152511954307556,0.8737732172012329,-1.455213189125061,1.308249592781067,1.1953096389770508,0.02658310905098915,1655.60302734375,1799.67529296875,226.49813842773438,405.0340576171875,81,2,81,2,0 -50.0,42,33,113,119,0,8,114.87722905959195,4.980997215647634,1.1815959430859828,1.6433986950503439,-0.03953022598060585,0.0,0.0,0.0,1.283260703086853,1.0854660272598267,-1.486018419265747,0.8469945788383484,0.6089851260185242,0.040747128427028656,21668.607421875,21998.025390625,2811.913330078125,5791.40185546875,115,5,115,5,2 -50.0,10,7,234,237,8,10,235.48559628027556,8.988897293788373,0.7382536265046045,0.543870799019284,-0.16362909755914234,0.0,0.0,0.0,0.9118001461029053,0.6713754534721375,-0.5174098014831543,1.451327919960022,1.9700416326522827,0.8732937574386597,992.6954956054688,1143.807373046875,160.06666564941406,316.67230224609375,235,9,235,9,0 -50.0,83,73,216,230,0,11,224.23032984032548,3.671993621384054,2.4369306863947315,1.9990428560229923,-0.5000359824055458,0.0,0.0,0.0,1.6624846458435059,1.2931041717529297,-0.579043447971344,0.4325534701347351,0.5273037552833557,0.21639586985111237,70867.1953125,71536.828125,8383.568359375,18228.2421875,224,4,224,4,3 -50.0,8,7,45,47,10,12,45.541925576583616,10.544006160100864,0.6186495756154291,0.5726784981925878,-0.003106473695514589,0.0,0.0,0.0,0.7866756319999695,0.7566171884536743,-0.06716755032539368,1.6164679527282715,1.7462279796600342,0.017536943778395653,882.380126953125,1112.0279541015625,164.48098754882812,309.51885986328125,46,11,46,11,1 -50.0,13,9,48,51,8,11,49.14595725780731,9.65512722912662,0.8383844876712105,0.7513224034473298,-0.09421707846252492,0.0,0.0,0.0,0.9479666352272034,0.8313038945198059,-0.568992018699646,1.2098195552825928,1.3500115871429443,0.3034267723560333,1499.4617919921875,1625.3521728515625,208.1859893798828,405.3729248046875,49,10,49,10,1 -50.0,8,7,73,75,12,14,73.82107046382019,13.063307855707151,0.5788165621106207,0.5613939228731764,0.1453195139389346,0.0,0.0,0.0,0.8459820747375488,0.6515557169914246,0.7554609775543213,1.8477460145950317,1.905090093612671,-0.9565958976745605,501.03759765625,607.4641723632812,80.17207336425781,138.1663055419922,74,13,73,13,0 -50.0,18,10,217,221,15,18,218.62319265144222,16.675378328636672,0.9828592477556186,0.80483752321051,0.014995551293736309,0.0,0.0,0.0,0.9920249581336975,0.8964280486106873,0.0834507867693901,1.0177290439605713,1.242840051651001,-0.03792419284582138,3953.64501953125,4157.92822265625,540.071533203125,985.4916381835938,219,17,218,17,0 -50.0,67,63,225,234,10,18,228.56185830478395,14.084248019689262,1.5359190360755761,1.404224886150022,0.011169483302278849,0.0,0.0,0.0,1.2397013902664185,1.184602975845337,0.08401411026716232,0.6511136293411255,0.7121778130531311,-0.010358174331486225,67426.46875,67754.7421875,8107.34619140625,16170.0498046875,228,14,228,14,0 -50.0,11,7,23,26,17,19,24.581328546482005,17.96724129375525,0.8157582348684786,0.5549258993517774,0.08588197218611415,0.0,0.0,0.0,0.9173309803009033,0.7274531126022339,0.2911715507507324,1.2461572885513306,1.8318898677825928,-0.3857179880142212,1070.7176513671875,1235.0218505859375,164.13992309570312,307.3323974609375,24,18,24,18,0 -50.0,18,10,153,157,15,19,155.08092629696216,17.604629899519768,1.1774583378461658,0.9739807100580435,0.06239050346354702,0.0,0.0,0.0,1.093190312385559,0.9779437184333801,0.2750496566295624,0.8521794676780701,1.0302112102508545,-0.10917650163173676,2185.889404296875,2414.61572265625,257.6316833496094,370.09228515625,155,18,155,18,0 -50.0,7,6,139,141,21,23,139.64714981673103,21.939137356855714,0.4119628217453225,0.5104114222132916,0.009565094234749938,0.0,0.0,0.0,0.715074896812439,0.6411256790161133,1.4748339653015137,2.428460121154785,1.9600566625595093,-0.09101853519678116,609.2726440429688,826.5860595703125,122.93231201171875,225.40711975097656,140,22,140,22,0 -50.0,13,9,14,17,21,24,15.727195596373775,22.732256738966377,0.769653863677394,0.7423195747449158,0.0928510728814187,0.0,0.0,0.0,0.9218667149543762,0.8137168884277344,0.7123257517814636,1.3191919326782227,1.3677682876586914,-0.33001524209976196,1519.193359375,1682.726318359375,234.17803955078125,473.5172119140625,16,23,16,23,0 -50.0,114,105,88,100,14,26,93.83858983036706,18.715897135177165,1.727520654201797,1.6939312081568225,0.04863937532187279,0.0,0.0,0.0,1.327472448348999,1.288125991821289,0.6191615462303162,0.5793326497077942,0.5908203721046448,-0.03326980024576187,197884.96875,198370.53125,23982.494140625,46233.66015625,94,19,94,19,0 -50.0,13,10,253,255,22,26,254.11850454858185,24.28463431454825,0.5390276766999262,0.9328741992048144,0.016650141254032302,0.0,0.0,0.0,0.9662178158760071,0.7337063550949097,1.528620958328247,1.8562157154083252,1.072547197341919,-0.06626027822494507,2978.974609375,3402.91064453125,480.17120361328125,927.0914916992188,254,24,254,24,2 -50.0,17,16,129,133,23,27,130.52157430265245,24.310205094648698,1.0170384530113648,1.0339786613211075,-0.16589429184450144,0.0,0.0,0.0,1.0916130542755127,0.9270372986793518,-0.8109046220779419,1.0096707344055176,0.9931287169456482,0.32398852705955505,2387.98095703125,2691.237548828125,285.29266357421875,545.118408203125,131,24,130,24,0 -50.0,16,9,21,26,25,28,23.781246182900166,26.42745026342176,1.1027621168266304,0.775486355343018,-0.07785265191438828,0.0,0.0,0.0,1.0584601163864136,0.8705806136131287,-0.22203485667705536,0.9132867455482483,1.298717975616455,0.18337343633174896,1910.4014892578125,2021.34521484375,255.996826171875,482.2738037109375,24,26,24,26,1 -50.0,21,16,59,63,24,28,60.49280130116813,26.08745273007607,0.9647619778236911,0.971693407925331,0.0741671461250002,0.0,0.0,0.0,1.021017074584961,0.9455049633979797,0.8087453842163086,1.0426430702209473,1.035205602645874,-0.1591651439666748,5934.5712890625,6168.3642578125,800.201416015625,1612.3111572265625,60,26,60,26,0 -50.0,15,10,169,173,25,28,171.04826859275826,26.435365967304318,0.8638521040188181,0.79983135350796,0.046056781781172784,0.0,0.0,0.0,0.9423003792762756,0.8807687163352966,0.4817103147506714,1.161170482635498,1.254113793373108,-0.13372762501239777,2064.26123046875,2240.90283203125,290.1407165527344,541.7506713867188,171,26,171,26,0 -50.0,31,26,30,35,20,25,31.92349681705268,22.584259280474996,1.2069042854998848,1.1667455150016472,-0.0053395126581614605,0.0,0.0,0.0,1.0989094972610474,1.0798368453979492,-0.12995263934135437,0.8285828828811646,0.8571022748947144,0.007583879865705967,10969.52734375,11104.056640625,1368.0557861328125,2679.17626953125,32,23,32,23,1 -50.0,19,13,33,37,25,29,35.000059816414975,27.52573820466265,1.0413188304395034,0.9617264034517561,0.06549909831936596,0.0,0.0,0.0,1.0383466482162476,0.961707592010498,0.5124094486236572,0.9644522666931152,1.0442702770233154,-0.131369486451149,3135.27490234375,3251.127197265625,404.26031494140625,798.3675537109375,35,28,35,28,1 -50.0,16,11,238,241,25,29,239.36547933748528,27.248073340385,0.8073973125198395,0.8794653718689291,-0.007567952346136497,0.0,0.0,0.0,0.9382172226905823,0.898115336894989,-1.4672895669937134,1.2386474609375,1.1371461153030396,0.021317554637789726,3438.5107421875,3676.095703125,490.60601806640625,943.47021484375,239,27,239,27,0 -50.0,14,9,201,204,28,31,202.46521133985317,29.321266962905504,0.8025402088364215,0.755874229673209,0.014947496695247642,0.0,0.0,0.0,0.8982858061790466,0.8668892979621887,0.28487518429756165,1.2465026378631592,1.3234589099884033,-0.0492994524538517,2432.982177734375,2642.892578125,345.11407470703125,636.370361328125,202,29,202,29,0 -50.0,28,22,112,118,24,28,114.69177347449725,25.834860955827253,1.7612436773798876,1.1135014864659336,-0.036963492600851744,0.0,0.0,0.0,1.3279104232788086,1.0542291402816772,-0.05681927874684334,0.5681764483451843,0.8986940383911133,0.037722062319517136,5278.1025390625,5529.18359375,556.9625854492188,1104.2666015625,114,26,114,26,1 -50.0,15,10,116,119,28,32,117.05498029517655,29.977874310840473,0.8463287483233679,0.9038708859526752,-0.04831013125904504,0.0,0.0,0.0,0.9650534987449646,0.9049150943756104,-1.0539684295654297,1.1851898431777954,1.1097384691238403,0.12669216096401215,1885.083740234375,1990.038818359375,279.6000671386719,607.3450317382812,117,30,117,30,1 -50.0,16,11,228,231,28,32,229.71307008861177,29.775971408587925,0.815036654876597,1.0365833005168685,0.13555059357858967,0.0,0.0,0.0,1.0492217540740967,0.8664604425430298,1.1279717683792114,1.2542154788970947,0.9861547946929932,-0.32801929116249084,2187.909423828125,2429.556884765625,277.0973815917969,503.38800048828125,230,30,229,30,0 -50.0,33,22,1,6,27,33,3.102878728604802,29.631401663618018,2.019270418439347,2.113068364623782,0.31196121025520185,0.0,0.0,0.0,1.543255090713501,1.3231412172317505,0.8600074052810669,0.5067873597145081,0.48429131507873535,-0.1496383100748062,3982.724609375,4205.2353515625,278.15777587890625,570.0148315429688,2,29,2,29,0 -50.0,34,23,102,110,29,34,107.2553854523455,31.714098276193393,1.5349862616425511,1.0339247649211298,-0.01464314742677253,0.0,0.0,0.0,1.239118218421936,1.0166106224060059,-0.029191041365265846,0.6515596508979797,0.9673190712928772,0.018455663695931435,15059.9970703125,15396.0537109375,1939.8463134765625,4100.3427734375,107,32,107,32,0 -50.0,13,9,84,87,32,35,85.35236075358502,33.30036200493199,0.7628510932638419,0.7416022206800807,0.07983566959399857,0.0,0.0,0.0,0.912560224533081,0.8195652365684509,0.7192474603652954,1.3258088827133179,1.3637968301773071,-0.28545448184013367,1796.208984375,1994.8328857421875,266.9436950683594,504.01092529296875,85,33,85,33,0 -50.0,8,7,28,31,34,36,29.519802660956735,35.046386993201665,0.577645900026944,0.4788075722995926,-0.005120974138338452,0.0,0.0,0.0,0.7602042555809021,0.6917679905891418,-0.05162736028432846,1.7313284873962402,2.0887198448181152,0.037034038454294205,700.5050659179688,882.997802734375,125.57062530517578,219.65757751464844,30,35,29,35,0 -50.0,17,10,65,69,34,37,67.09432627666685,35.34690953376082,0.9483960239567777,0.8050776807513096,-0.03859645646614185,0.0,0.0,0.0,0.9788407683372498,0.8918208479881287,-0.24702882766723633,1.0564730167388916,1.244544267654419,0.10129734873771667,2895.805419921875,3063.060791015625,418.1146240234375,847.0676879882812,67,35,67,35,0 -50.0,15,9,188,191,36,39,189.49518434191882,37.624268016560585,0.8349555865136784,0.8024311993157056,0.05482053648380125,0.0,0.0,0.0,0.935882031917572,0.8726463317871094,0.6412105560302734,1.2030649185180664,1.2518278360366821,-0.16438210010528564,2433.4775390625,2620.475830078125,327.99957275390625,596.953369140625,190,38,189,38,0 -50.0,13,8,166,169,39,42,167.47518466101698,40.57583835396964,0.7573567040899127,0.7777076646438377,0.10690982525111448,0.0,0.0,0.0,0.9353743195533752,0.8124895095825195,0.8328443169593811,1.3465111255645752,1.311275839805603,-0.37020406126976013,1459.3192138671875,1651.7314453125,204.26963806152344,373.48382568359375,167,40,167,40,0 -50.0,9,7,124,127,41,43,125.64111156641165,41.96227520745003,0.6534287718648715,0.5126410326412089,-0.09102945029526643,0.0,0.0,0.0,0.8355281352996826,0.6840778589248657,-0.4562718868255615,1.5692065954208374,2.0001614093780518,0.5572866797447205,820.4144897460938,1004.1516723632812,142.79139709472656,256.9178466796875,126,42,126,42,0 -50.0,15,14,213,216,40,43,214.38978906128256,41.62693068907014,0.8616553371133313,0.8789113384669851,0.05922796364375005,0.0,0.0,0.0,0.9644358158111572,0.9002389907836914,0.8577266335487366,1.1659576892852783,1.1430659294128418,-0.15714280307292938,2235.654052734375,2450.044189453125,287.2077941894531,529.9528198242188,214,42,214,42,0 -50.0,19,12,235,238,40,45,236.32924938856812,42.04015716093038,0.8145661118872942,1.2955563385560076,-0.007666228437437805,0.0,0.0,0.0,1.1382787227630615,0.9024654626846313,-1.5548633337020874,1.2277158498764038,0.771912157535553,0.01452958770096302,2702.0673828125,2908.273193359375,351.88946533203125,745.0547485351562,236,42,236,42,0 -50.0,27,17,245,250,40,45,247.05319712464015,42.28677041697422,1.0732242073186624,1.120739702354868,0.08735015194785056,0.0,0.0,0.0,1.0897271633148193,1.0032241344451904,0.9181777238845825,0.9377202391624451,0.8979641199111938,-0.14617133140563965,9696.3662109375,9872.365234375,1284.419189453125,2627.218994140625,247,42,247,42,0 -50.0,22,20,0,5,44,47,2.4703948470179253,45.57023342253004,1.5209958798056373,0.8467976711597589,-0.044072572706580715,0.0,0.0,0.0,1.2344491481781006,0.9186559915542603,-0.06500165909528732,0.6584569811820984,1.1827032566070557,0.06854032725095749,5736.6044921875,6058.4091796875,584.5291748046875,1012.9666137695312,3,45,3,45,2 -50.0,12,9,71,74,44,47,72.4424360728761,45.51879007986595,0.7512239571024777,0.7383287774538023,-0.021478146705735224,0.0,0.0,0.0,0.8759003281593323,0.8499125242233276,-0.6395812034606934,1.3322690725326538,1.3555375337600708,0.0775119960308075,1163.448486328125,1337.0059814453125,161.4994659423828,311.62921142578125,72,46,72,46,0 -50.0,16,9,12,16,46,49,13.95921607419027,47.47795607432384,0.9430468190693331,0.7870954024714534,0.013183616789322006,0.0,0.0,0.0,0.9716755747795105,0.8865600824356079,0.08374471217393875,1.0606410503387451,1.2707915306091309,-0.035530854016542435,2008.5849609375,2123.098876953125,272.3307800292969,504.41802978515625,14,47,14,47,1 -50.0,17,9,17,21,46,50,18.72597039000662,48.00849141309172,0.9033394192635429,0.8863267392929401,0.007650609382509277,0.0,0.0,0.0,0.9519841074943542,0.9398895502090454,0.366241991519928,1.1070845127105713,1.1283345222473145,-0.019112300127744675,2751.274169921875,2902.067626953125,396.1415710449219,812.0254516601562,19,48,19,48,1 -50.0,11,7,224,227,48,50,225.38862302350998,49.1158059708202,0.8085517082617493,0.540539019443534,0.08786137747350065,0.0,0.0,0.0,0.9136666655540466,0.7171498537063599,0.29016873240470886,1.2590171098709106,1.883269190788269,-0.4092913866043091,1238.264892578125,1442.6507568359375,197.9229736328125,378.85107421875,225,49,225,49,0 -50.0,15,9,59,63,48,51,60.85277039074554,49.66490048206532,0.8592394330266915,0.7884839358973754,0.04962131525629454,0.0,0.0,0.0,0.9406397342681885,0.8734530806541443,0.47571438550949097,1.1680651903152466,1.2728828191757202,-0.1470186710357666,2221.733154296875,2388.537841796875,329.3011169433594,665.668701171875,61,50,61,50,0 -50.0,20,13,93,97,47,51,94.9211888018082,49.417225936743264,1.0641210484786443,0.9636780765249746,0.11412623777785669,0.0,0.0,0.0,1.067046046257019,0.9429803490638733,0.5781229138374329,0.9518322348594666,1.051040530204773,-0.22544671595096588,4165.48095703125,4363.4736328125,550.4712524414062,1063.6644287109375,95,49,95,49,1 -50.0,8,6,98,100,51,53,99.42724115657408,51.53286506091032,0.6305993830177563,0.5532086065728457,0.01814058158456433,0.0,0.0,0.0,0.7966433167457581,0.7410582900047302,0.21919071674346924,1.5872901678085327,1.8093432188034058,-0.10409948974847794,731.587890625,922.6113891601562,138.41310119628906,285.26654052734375,99,52,99,52,1 -50.0,17,11,145,149,47,50,146.90277093081167,48.39331266431002,0.9447093448134627,0.7953860331933464,0.05696544336222864,0.0,0.0,0.0,0.9818143844604492,0.8809857368469238,0.32587873935699463,1.0631178617477417,1.2627042531967163,-0.15228071808815002,3559.39599609375,3762.44921875,509.88818359375,1002.3045043945312,147,48,147,48,1 -50.0,18,12,149,153,50,53,151.3002264236198,51.70965457551608,1.0094032981397483,0.8170183829695237,0.13385793995690465,0.0,0.0,0.0,1.0382903814315796,0.865086555480957,0.47384268045425415,1.0126864910125732,1.251145839691162,-0.33183130621910095,4151.94580078125,4379.0009765625,600.5,1286.5926513671875,151,52,151,52,1 -50.0,12,7,165,168,51,54,166.53748256895483,52.51515487886505,0.6996930065283617,0.6899955222429308,0.0019507103028590933,0.0,0.0,0.0,0.836702287197113,0.8304322957992554,0.19124922156333923,1.4292094707489014,1.449296236038208,-0.008081135340034962,1552.9241943359375,1754.5030517578125,222.06394958496094,389.4140625,167,53,166,53,0 -50.0,25,19,67,72,51,55,69.45793917789427,53.22964398192084,1.0963872566351025,0.9750676496469515,0.05318685390227529,0.0,0.0,0.0,1.056599497795105,0.977267861366272,0.35992586612701416,0.9145063757896423,1.028290867805481,-0.09976685792207718,10416.8623046875,10651.615234375,1319.7869873046875,2442.309814453125,69,53,69,53,0 -50.0,11,8,7,10,54,57,8.12832478156011,55.842536736876646,0.6712676800045687,0.6708677809155223,0.025725292049533,0.0,0.0,0.0,0.8347417712211609,0.8033316135406494,0.7815120220184326,1.4919111728668213,1.4928004741668701,-0.11441852152347565,1310.1162109375,1515.54638671875,221.0626220703125,471.13189697265625,8,56,8,56,0 -50.0,90,79,53,63,36,46,56.97294009324406,41.15509037556166,1.5289100428843234,1.4790528306163964,0.02320267289381306,0.0,0.0,0.0,1.2401763200759888,1.2124048471450806,0.37477731704711914,0.654216468334198,0.6762693524360657,-0.020526070147752762,173206.171875,173430.671875,22553.21875,46989.5,57,41,57,41,1 -50.0,175,152,42,56,40,57,47.217420835020874,46.56632956294584,3.0244640846767084,3.4981258726178623,0.4367944991838044,0.0,0.0,0.0,1.9385982751846313,1.6626564264297485,1.0338164567947388,0.33670899271965027,0.2911171019077301,-0.08408652991056442,324472.40625,324981.15625,34615.9375,67723.078125,47,47,47,47,1 -50.0,7,5,89,91,55,57,89.64207030100586,55.89719674633583,0.4145405780406549,0.5040085637524265,0.011491776570903278,0.0,0.0,0.0,0.7109578251838684,0.6427192687988281,1.4450693130493164,2.413834810256958,1.985348105430603,-0.11007452011108398,592.8243408203125,803.640380859375,117.62696075439453,221.8535919189453,90,56,89,56,0 -50.0,11,8,159,162,55,58,160.37463483617245,56.79844681852832,0.6615802966593232,0.7583017123029308,0.06177578090163793,0.0,0.0,0.0,0.8879160284996033,0.7946616411209106,1.117493748664856,1.5231186151504517,1.3288447856903076,-0.24816465377807617,1206.931884765625,1359.292724609375,198.0387420654297,429.97308349609375,160,57,160,57,1 -50.0,11,10,93,96,56,59,94.14855039841134,57.146241883926024,0.6729101787535434,0.6633779926687697,-0.009135258965327742,0.0,0.0,0.0,0.823679506778717,0.8110735416412354,-0.544960081577301,1.4863603115081787,1.5077180862426758,0.040936801582574844,1415.580078125,1645.8800048828125,241.67974853515625,516.0671997070312,94,57,94,57,0 -50.0,22,12,103,107,55,59,104.90915821018359,56.909244763151065,0.9822782507113006,0.9486182579174409,0.06519308635892651,0.0,0.0,0.0,1.0162571668624878,0.9476907849311829,0.659078061580658,1.0227062702178955,1.0589951276779175,-0.14056944847106934,6809.1884765625,7001.2041015625,999.5093994140625,2167.06982421875,105,57,105,57,0 -50.0,52,46,214,220,52,59,216.4647238459248,55.66048672074991,1.4123233192146536,1.4613912194109915,-0.049217274668951205,0.0,0.0,0.0,1.2214133739471436,1.1755270957946777,-1.016614556312561,0.708885133266449,0.6850835084915161,0.04774819314479828,34788.5703125,35065.48828125,4246.23095703125,8999.10546875,216,56,216,56,0 -50.0,9,8,40,42,59,61,40.99749004593315,60.08854677220082,0.5671819518682533,0.5607913432542886,0.008324659518423427,0.0,0.0,0.0,0.756903886795044,0.7450301051139832,0.6021507978439331,1.7634868621826172,1.7835830450057983,-0.052356112748384476,906.814208984375,1101.7022705078125,169.65953063964844,359.61968994140625,41,60,41,60,0 -50.0,7,4,59,61,59,61,59.64030684666617,59.85945761468638,0.4079130639428453,0.5000211503258435,0.020463429434385394,0.0,0.0,0.0,0.7101850509643555,0.6352726817131042,1.3617298603057861,2.4565460681915283,2.0040297508239746,-0.2010689377784729,629.0707397460938,856.006591796875,125.40644073486328,230.80812072753906,60,60,59,60,0 -50.0,61,56,127,135,53,61,130.36532174936784,56.526262442087784,1.4530243398717317,1.3744049686478768,-0.026478411643674704,0.0,0.0,0.0,1.2087639570236206,1.1688964366912842,-0.2963884472846985,0.688461422920227,0.7278431057929993,0.0265269186347723,62156.94140625,62522.06640625,7269.6201171875,14435.580078125,130,57,130,57,0 -50.0,10,7,194,196,58,61,195.04094413804705,59.25707837499581,0.524295909306034,0.7070684575293911,0.00797178207239524,0.0,0.0,0.0,0.8410799503326416,0.7238430976867676,1.5272905826568604,1.907646894454956,1.4145326614379883,-0.04301520064473152,1128.482666015625,1337.209716796875,201.6759033203125,423.78289794921875,195,59,195,59,0 -50.0,8,6,123,125,64,66,123.90126742911421,65.24121921438001,0.5271694819114041,0.49267812159797053,0.07370020469487026,0.0,0.0,0.0,0.7652547359466553,0.6589633822441101,0.67046719789505,1.9374415874481201,2.07307767868042,-0.5796476006507874,813.8740844726562,1069.7760009765625,160.62423706054688,319.71099853515625,124,65,124,65,0 -50.0,11,7,26,29,58,60,27.491194806595814,58.556263962122394,0.8459219108260738,0.6642218565686349,-0.13108373695202769,0.0,0.0,0.0,0.9563266634941101,0.7717403173446655,-0.48236873745918274,1.2194339036941528,1.5530140399932861,0.4813089370727539,1075.3558349609375,1217.0023193359375,162.2681427001953,316.349365234375,27,59,27,59,1 -50.0,17,11,104,108,65,68,106.00342148640459,66.67707697785178,0.9892502632323055,0.8320543293570033,-0.09697992731543481,0.0,0.0,0.0,1.0175869464874268,0.8864656686782837,-0.44485610723495483,1.0225505828857422,1.215735912322998,0.23836635053157806,2510.927001953125,2700.501953125,373.7049560546875,799.419921875,106,67,106,67,0 -50.0,10,8,79,82,68,70,80.18381509666087,69.02563156565041,0.6918586194062517,0.5352209566948307,0.009525211569031411,0.0,0.0,0.0,0.8321272134780884,0.7311934232711792,0.06051328405737877,1.445736289024353,1.8688451051712036,-0.05145891010761261,1091.85400390625,1306.32568359375,198.05926513671875,429.91693115234375,80,69,80,69,0 -50.0,34,25,149,156,64,70,153.42593708104195,67.37515025433171,1.533145499819625,1.1382627742421718,0.2867772124989951,0.0,0.0,0.0,1.2976428270339966,0.9937461614608765,0.48392075300216675,0.6845123767852783,0.9219813346862793,-0.34491604566574097,15452.6748046875,15620.5400390625,1803.148681640625,3189.898193359375,153,67,153,67,1 -50.0,15,12,156,159,66,70,157.46205694287892,68.48084398373125,0.7201013177210864,1.0036999593884701,-0.08415829752960713,0.0,0.0,0.0,1.0133081674575806,0.834869921207428,-1.3029820919036865,1.402436375617981,1.0061734914779663,0.23518314957618713,3186.695556640625,3425.92529296875,455.45867919921875,735.4257202148438,157,68,157,69,1 -50.0,78,71,2,12,62,71,5.205185147234452,66.28856961813439,1.8288817101136665,1.4712567428956511,-0.12702753209442896,0.0,0.0,0.0,1.3672633171081543,1.1961311101913452,-0.3088342845439911,0.5500809550285339,0.6837915778160095,0.0949873998761177,81830.890625,82188.515625,10057.6025390625,19637.751953125,5,66,5,66,0 -50.0,13,9,84,87,68,71,85.5903932880333,69.07745220575558,0.8456691316656801,0.65728112472287,0.03068185734972584,0.0,0.0,0.0,0.9222473502159119,0.8077190518379211,0.1574462205171585,1.1845016479492188,1.5240000486373901,-0.11058498173952103,1915.1639404296875,2112.34765625,288.9017028808594,551.193603515625,86,69,86,69,0 -50.0,57,48,164,172,62,71,166.5048291814193,65.0726886665243,1.51816967688388,1.7537537451896643,0.12477213196638015,0.0,0.0,0.0,1.344452142715454,1.2101123332977295,1.1637130975723267,0.6625620126724243,0.5735591650009155,-0.09427694976329803,35344.453125,35744.859375,4425.66357421875,9423.681640625,166,65,166,65,0 -50.0,11,7,66,68,69,72,66.97904156541534,70.66462418268841,0.5519777627135175,0.7658475355188386,0.06620727381929892,0.0,0.0,0.0,0.8858240246772766,0.7301651239395142,1.2936104536056519,1.8306496143341064,1.3194243907928467,-0.3165181577205658,1410.7225341796875,1645.10107421875,239.17259216308594,502.91351318359375,67,71,67,71,0 -50.0,15,8,58,62,71,74,59.898670484045624,72.39023118891329,0.8349668559575312,0.7901734954258903,-0.02767087605794849,0.0,0.0,0.0,0.9209610223770142,0.8814597129821777,-0.4451763331890106,1.199043869972229,1.2670152187347412,0.08397799730300903,2171.390869140625,2363.817138671875,319.5237731933594,622.761962890625,60,72,60,72,0 -50.0,26,21,177,181,69,74,178.68902320944028,71.31259119644575,1.016324102880207,1.0593716395942288,0.04036255814825518,0.0,0.0,0.0,1.0409566164016724,0.9960446953773499,1.030348539352417,0.9854291677474976,0.9453862905502319,-0.07509063184261322,13621.7607421875,13898.130859375,1735.553466796875,3217.331298828125,179,71,179,71,0 -50.0,11,8,42,45,72,75,43.87273738231518,73.20779608361448,0.6717470202763223,0.6566413655907855,0.028622640533527477,0.0,0.0,0.0,0.8329445123672485,0.7966127395629883,0.6564005613327026,1.4914257526397705,1.5257351398468018,-0.130020871758461,1398.155029296875,1600.9876708984375,235.64500427246094,484.0445556640625,44,73,44,73,0 -50.0,30,24,91,97,71,76,93.75298785406925,73.22827118595642,1.2277713215651387,1.0001075340883459,0.05549479669715751,0.0,0.0,0.0,1.1138124465942383,0.993630051612854,0.22680504620075226,0.8165318369865417,1.0024065971374512,-0.09061679244041443,15749.5068359375,16059.84375,2061.26123046875,4095.39404296875,94,73,94,73,0 -50.0,5,4,72,74,75,77,72.98574318678037,76.06601543371639,0.35703867486019336,0.35679640165720383,0.0009411374353014423,0.0,0.0,0.0,0.5982193946838379,0.5966310501098633,0.7213935852050781,2.8008365631103516,2.8027384281158447,-0.014775777235627174,354.60479736328125,528.4666748046875,99.85798645019531,215.0952606201172,73,76,73,76,0 -50.0,10,9,217,219,71,74,217.99927933269018,71.98577180072306,0.5371452878225622,0.726141308737815,0.00901700079589518,0.0,0.0,0.0,0.8523910641670227,0.7326090931892395,1.5232303142547607,1.8620818853378296,1.3774296045303345,-0.046245526522397995,1408.4268798828125,1643.93896484375,256.36505126953125,566.9398803710938,218,72,218,72,1 -50.0,9,7,217,219,75,77,217.94734850411672,75.99221978003467,0.5640677430650891,0.5626230270537191,0.010226329468436601,0.0,0.0,0.0,0.7573620080947876,0.7437025904655457,0.7501381635665894,1.773421049118042,1.7779749631881714,-0.06446798890829086,1101.4808349609375,1341.152099609375,209.23291015625,454.83984375,218,76,218,76,1 -50.0,8,6,47,49,76,78,47.786355467175184,76.80675091316708,0.5131760765087496,0.5113474499060164,-0.07184503768884931,0.0,0.0,0.0,0.7642726302146912,0.6636345982551575,-0.7790353894233704,1.9877485036849976,1.9948569536209106,0.5585629343986511,703.3800048828125,922.217041015625,134.64474487304688,252.4078826904297,48,77,48,77,0 -50.0,7,5,141,143,76,78,142.33404748526087,77.10946653899374,0.40452772028940975,0.4944893305547944,0.01912777720525871,0.0,0.0,0.0,0.7059655785560608,0.6329531073570251,1.3697580099105835,2.476548194885254,2.025994062423706,-0.19159507751464844,703.0013427734375,948.8329467773438,150.17398071289062,308.20941162109375,142,77,142,77,0 -50.0,10,8,87,90,79,81,88.16297983996475,79.95569110506443,0.6875578369254203,0.5419307647458289,0.026563724346311046,0.0,0.0,0.0,0.8320168256759644,0.732964277267456,0.17490734159946442,1.4571826457977295,1.8487552404403687,-0.14285293221473694,1203.22607421875,1440.9869384765625,216.2382049560547,470.15386962890625,88,80,88,80,0 -50.0,9,7,78,80,82,84,79.03738126243424,83.03669107281372,0.5692265142943824,0.56547402746985,0.03817927874218263,0.0,0.0,0.0,0.7781873941421509,0.7274097204208374,0.7608464360237122,1.7647616863250732,1.7764726877212524,-0.23830388486385345,831.7071533203125,1021.0769653320312,155.7019500732422,334.05712890625,79,83,79,83,0 -50.0,24,20,107,113,77,81,108.88589250127895,79.17206572664222,1.6630418311698296,1.0313481052464013,-0.012928591530977585,0.0,0.0,0.0,1.2896922826766968,1.0154228210449219,-0.0204551313072443,0.601366400718689,0.9696992039680481,0.01507700514048338,6656.8134765625,6891.40087890625,822.474853515625,1650.5030517578125,109,79,109,79,1 -50.0,32,21,150,155,81,86,152.1915019243307,83.47482405516138,1.1492566322395783,1.0909030641882893,0.06673741126388855,0.0,0.0,0.0,1.0922071933746338,1.0233490467071533,0.579323947429657,0.8732298612594604,0.9199398159980774,-0.10684193670749664,16660.146484375,16847.96484375,2062.487548828125,4026.29443359375,152,83,152,84,0 -50.0,8,7,13,16,87,89,14.537640039489496,88.04199781544096,0.5558945741577923,0.4728807123588019,0.0022315397449943486,0.0,0.0,0.0,0.7456235885620117,0.6876196265220642,0.026855675503611565,1.798936367034912,2.1147382259368896,-0.01697847992181778,808.5368041992188,1039.711669921875,153.71751403808594,292.8377685546875,15,88,15,88,0 -50.0,14,9,96,99,86,89,97.25063750396357,87.4836281346407,0.8118716298124662,0.787019834846094,0.0013884298383848304,0.0,0.0,0.0,0.9010820984840393,0.8870977759361267,0.05563761293888092,1.2317255735397339,1.2706198692321777,-0.0043459245935082436,1696.5872802734375,1884.2850341796875,232.09579467773438,433.345703125,97,87,97,88,0 -50.0,9,6,63,65,87,90,63.908402761223044,88.41506685587474,0.49813719881276264,0.6256407290279649,0.07416795524263264,0.0,0.0,0.0,0.8122134208679199,0.6812394857406616,1.1404069662094116,2.043548822402954,1.6270803213119507,-0.4845139682292938,942.4561157226562,1193.5692138671875,168.19570922851562,317.16461181640625,64,88,64,89,0 -50.0,13,11,104,108,87,90,106.04544751542434,88.3029391614934,0.831381285457792,0.8669059081367607,-0.2510220833721033,0.0,0.0,0.0,1.0491869449615479,0.7729772925376892,-0.8207192420959473,1.3180525302886963,1.2640405893325806,0.7633130550384521,1623.940185546875,1921.551025390625,253.93472290039062,548.8900756835938,106,88,106,88,0 -50.0,17,10,26,30,88,91,27.872758445951092,89.37326770964539,0.9519736159033001,0.7947170325585577,0.060261782603418634,0.0,0.0,0.0,0.9861087203025818,0.8799319267272949,0.3269616365432739,1.0555157661437988,1.264378547668457,-0.16007524728775024,3606.160888671875,3815.175537109375,513.11181640625,1005.8435668945312,28,89,28,89,0 -50.0,21,15,218,222,85,89,219.65460767106774,86.70083231571786,0.987209395204216,0.9400305120509111,0.028369981582315074,0.0,0.0,0.0,1.000257968902588,0.9626650214195251,0.43857255578041077,1.0138356685638428,1.0647187232971191,-0.06119481846690178,6562.6640625,6767.4033203125,865.1251220703125,1547.4525146484375,220,87,220,87,1 -50.0,9,6,216,218,89,91,216.5122165696376,90.47537621471616,0.7462923587697412,0.6879562504681256,-0.17294493584333082,0.0,0.0,0.0,0.9447283744812012,0.7360278367996216,-0.701856791973114,1.422847867012024,1.5435000658035278,0.7153778672218323,750.8297119140625,934.130126953125,120.3340835571289,197.25733947753906,217,90,216,90,1 -50.0,14,13,178,181,91,94,179.08084279508742,92.47227893119593,0.7880871243494632,0.8790690122552984,-0.008901329872302188,0.0,0.0,0.0,0.9380467534065247,0.8872566819190979,-1.474180817604065,1.2690403461456299,1.1376972198486328,0.025700250640511513,2535.501953125,2826.390625,345.606689453125,668.9977416992188,179,92,179,92,1 -50.0,24,17,167,172,86,90,168.46351797219432,88.30728881616878,1.5687062054058245,0.9362546632953848,-0.10423690086202964,0.0,0.0,0.0,1.2591437101364136,0.9589149355888367,-0.1592060774564743,0.642219066619873,1.0760458707809448,0.143001526594162,4649.4951171875,4812.7890625,556.3405151367188,1017.7279663085938,168,88,168,88,1 -50.0,10,7,133,136,97,99,134.74349123419523,98.07858266543126,0.6747454595487201,0.5278032535465733,0.017223509016751404,0.0,0.0,0.0,0.8226404190063477,0.7251285910606384,0.11513378471136093,1.4832758903503418,1.896224856376648,-0.09680582582950592,1209.7637939453125,1461.0909423828125,214.9168243408203,425.70892333984375,135,98,135,98,0 -50.0,29,24,201,205,87,94,202.81929313043062,90.66446743091132,1.0392504327420218,1.2605935516311462,0.068716673947395,0.0,0.0,0.0,1.1314555406570435,1.009778380393982,1.2929712533950806,0.9657127857208252,0.7961466908454895,-0.10528463870286942,11776.9892578125,12014.275390625,1529.7327880859375,3019.0029296875,203,91,203,91,1 -50.0,22,14,202,206,94,99,203.4895881371497,96.59779262126388,0.9452541078064609,1.0379948358299096,0.01308541814889086,0.0,0.0,0.0,1.0197086334228516,0.971310019493103,1.4332754611968994,1.0581012964248657,0.9635640978813171,-0.026677776128053665,6988.19580078125,7210.88037109375,869.6959838867188,1698.1177978515625,203,97,203,97,1 -50.0,9,6,171,173,97,100,171.8652390327951,98.61978331353319,0.4948672236241016,0.6197697007023248,-0.0689676905605432,0.0,0.0,0.0,0.8064489364624023,0.6813787817955017,-1.153324842453003,2.0525765419006348,1.6389199495315552,0.4568195939064026,952.9740600585938,1191.7364501953125,173.76284790039062,334.2960205078125,172,99,172,99,0 -50.0,10,7,66,69,100,102,67.72271088195066,100.9410191964987,0.6672926500725249,0.5351188796341785,0.004196865977797781,0.0,0.0,0.0,0.8169612884521484,0.7314271926879883,0.031710054725408554,1.498666763305664,1.8688358068466187,-0.02350768633186817,1189.7635498046875,1431.0726318359375,207.9290008544922,388.53662109375,68,101,68,101,0 -50.0,22,13,77,81,98,102,78.8659521220364,99.87773794311825,0.9871562070665072,0.940948777769675,0.06490586748933946,0.0,0.0,0.0,1.0163403749465942,0.9461275339126587,0.6144121289253235,1.0176262855529785,1.0675990581512451,-0.1403900384902954,7628.44677734375,7832.5703125,1110.9893798828125,2355.60791015625,79,100,79,100,0 -50.0,8,5,40,42,101,103,40.73383813857798,101.80780464575784,0.4899328024644415,0.5441756475636338,-0.06214336710521973,0.0,0.0,0.0,0.7647601962089539,0.6702613830566406,-0.9911554455757141,2.0710957050323486,1.864651083946228,0.47302690148353577,722.5068359375,940.142578125,127.46356964111328,200.9961700439453,41,102,41,102,0 -50.0,8,7,54,56,101,103,54.77458905600095,101.85461361077016,0.4995666020719882,0.5186317134660454,-0.06331289916404959,0.0,0.0,0.0,0.757050633430481,0.6671376824378967,-0.8601182103157043,2.033191680908203,1.9584506750106812,0.4964110255241394,871.1542358398438,1152.79443359375,171.6039581298828,329.2919921875,55,102,55,102,0 -50.0,13,10,242,245,100,103,243.72014724095408,101.74784908409174,0.8020171496277202,0.7491945044833637,0.07843377908445692,0.0,0.0,0.0,0.9264810085296631,0.8323729038238525,0.6229941248893738,1.2597538232803345,1.348573923110962,-0.2637692987918854,1490.1400146484375,1694.678955078125,222.41465759277344,439.3994140625,244,102,244,102,1 -50.0,11,6,220,223,103,106,221.66323334954953,104.58963580623757,0.6112953644674546,0.7063913045693222,-0.039950486930354856,0.0,0.0,0.0,0.8490859270095825,0.7724893689155579,-1.2214035987854004,1.6419392824172974,1.4208978414535522,0.1857222020626068,1039.5728759765625,1220.9161376953125,163.4966583251953,274.51116943359375,222,105,222,105,0 -50.0,15,7,67,71,105,108,69.0808935386308,106.54763514618755,0.8998936252469711,0.7661560588174217,-0.024811380408311656,0.0,0.0,0.0,0.950972318649292,0.8727550506591797,-0.17764973640441895,1.1122355461120605,1.3063836097717285,0.07203780114650726,1690.283447265625,1820.15478515625,240.1971893310547,487.38397216796875,69,107,69,107,0 -50.0,41,34,246,253,102,108,249.59189862841166,104.36477525640746,1.4117340841414574,1.3968169050142079,-0.1619247032451856,0.0,0.0,0.0,1.2515478134155273,1.1145309209823608,-0.7623834013938904,0.7178940773010254,0.7255607843399048,0.166442409157753,16093.6025390625,16353.4111328125,1862.1607666015625,3363.99853515625,250,104,250,104,0 -50.0,5,5,132,134,108,110,132.99217278902427,109.01703314809805,0.3597351534614812,0.35155328044935286,0.00013332204374427725,0.0,0.0,0.0,0.5997810363769531,0.5929174423217773,0.016289042308926582,2.7798233032226562,2.8445193767547607,-0.0021084242034703493,363.06585693359375,549.9960327148438,104.69373321533203,237.30137634277344,133,109,133,109,0 -50.0,12,10,5,8,109,112,6.51431309833487,110.55122638931897,0.7025297444894716,0.7194747691656493,-0.0015934557965922025,0.0,0.0,0.0,0.8483061194419861,0.8380818367004395,-1.477845311164856,1.4234343767166138,1.3899097442626953,0.006305098999291658,1683.265380859375,1910.06494140625,238.23785400390625,462.50323486328125,6,111,6,111,0 -50.0,8,6,17,20,111,113,18.492091215720258,111.8890374117485,0.5507939569777109,0.47600232644063933,0.0011358028380572538,0.0,0.0,0.0,0.7421665787696838,0.689916729927063,0.015181561931967735,1.8155698776245117,2.1008403301239014,-0.008664366789162159,685.1728515625,889.3523559570312,127.44744873046875,249.7821807861328,18,112,18,112,0 -50.0,13,9,210,213,110,113,211.33525910775185,111.23404278455332,0.7473143439911119,0.7245688028410351,0.08145788697906275,0.0,0.0,0.0,0.9045382738113403,0.8085132241249084,0.7160388231277466,1.354725956916809,1.397253394126892,-0.30460354685783386,1913.311279296875,2136.72265625,303.7465515136719,629.5105590820312,211,111,211,111,0 -50.0,11,8,241,244,111,113,242.354906148954,112.07926779992404,0.7902398484857989,0.5456384622857913,0.06845652584305983,0.0,0.0,0.0,0.8989412188529968,0.7264867424964905,0.25514498353004456,1.2793430089950562,1.8528529405593872,-0.3210161328315735,1253.369140625,1455.409423828125,208.9306640625,435.893310546875,242,112,242,112,0 -50.0,11,6,72,75,112,115,73.65819849372106,113.44775209154726,0.6061864486648041,0.7014866895267877,0.05168076124056231,0.0,0.0,0.0,0.8509594202041626,0.7638987302780151,1.157819390296936,1.6600844860076904,1.4345543384552002,-0.24460744857788086,1080.5152587890625,1282.27099609375,167.63241577148438,298.0770263671875,74,113,74,113,0 -50.0,9,7,174,177,113,115,175.63029376737381,114.10271811051435,0.6415568467899386,0.5036062453783383,0.08134196471292832,0.0,0.0,0.0,0.8241547346115112,0.6825921535491943,0.43374186754226685,1.5912960767745972,2.0271925926208496,-0.5140489935874939,959.1956787109375,1190.1893310546875,170.06741333007812,318.2071533203125,176,114,176,114,0 -50.0,7,4,151,153,115,117,152.14404780441018,115.64441863318321,0.49430707482432723,0.39771812599225603,-0.013383898722787446,0.0,0.0,0.0,0.7043630480766296,0.6292041540145874,-0.13517317175865173,2.024878978729248,2.516636610031128,0.1362813115119934,725.5797729492188,985.7611694335938,151.8822479248047,321.96038818359375,152,116,152,116,0 -50.0,11,7,229,231,116,119,229.95388740495787,117.64733846227216,0.551972896170129,0.8203357618382778,0.08580293910433423,0.0,0.0,0.0,0.9194693565368652,0.725868284702301,1.2863332033157349,1.8416262865066528,1.2391606569290161,-0.38524943590164185,1210.7056884765625,1392.96142578125,199.51052856445312,423.07171630859375,230,118,230,118,0 -50.0,13,11,80,83,117,120,81.3133618036198,118.55404563517213,0.8281841001780519,0.7613766725707034,-0.12430838277887424,0.0,0.0,0.0,0.9609883427619934,0.81612628698349,-0.6541405916213989,1.2377945184707642,1.3464055061340332,0.4041842520236969,1592.897216796875,1857.0430908203125,211.8890380859375,344.42694091796875,81,119,81,119,0 -50.0,14,9,115,118,116,119,116.07910396402217,117.44845262631881,0.7818815528007574,0.7826066170800168,0.03091000664328658,0.0,0.0,0.0,0.9017517566680908,0.8667940497398376,0.7912622094154358,1.2809661626815796,1.2797794342041016,-0.10118665546178818,1765.6484375,1933.810302734375,257.0968017578125,517.3839111328125,116,118,116,118,1 -50.0,29,19,119,124,115,120,121.28093171402425,117.8360252261571,1.0808465183740168,1.1337906326589433,0.04343273925977709,0.0,0.0,0.0,1.0761890411376953,1.0278396606445312,1.0590842962265015,0.9266271591186523,0.8833568692207336,-0.07099362462759018,11105.8759765625,11310.720703125,1489.562744140625,3248.949951171875,121,118,121,118,1 -50.0,13,10,6,9,120,123,7.742998637432939,121.1436657421138,0.8279787233310367,0.8693375906652803,0.2583603140859756,0.0,0.0,0.0,1.0525420904159546,0.767770528793335,0.8253335356712341,1.3312103748321533,1.2678778171539307,-0.7912505865097046,1572.27783203125,1849.9072265625,218.49755859375,396.73675537109375,8,121,7,121,0 -50.0,10,10,67,70,121,123,68.28271740138989,121.96018696713212,0.7469489876832953,0.5286760380008309,0.007397943504840798,0.0,0.0,0.0,0.8644070029258728,0.7269288897514343,0.033841315656900406,1.3389650583267212,1.8917797803878784,-0.03747318685054779,1016.2997436523438,1259.534423828125,165.78225708007812,288.93780517578125,68,122,68,122,0 -50.0,9,6,237,239,121,123,238.096687724997,122.04358699391723,0.5619225843824871,0.5686568125859361,0.022084985882866892,0.0,0.0,0.0,0.7665702104568481,0.7368510961532593,0.8610464334487915,1.7823251485824585,1.7612181901931763,-0.13844069838523865,752.3870239257812,909.8067626953125,139.5619354248047,297.69671630859375,238,122,238,122,0 -50.0,15,12,14,17,121,124,15.581739275821477,122.42835316838207,0.8170912136796016,0.8245553356475881,0.0753780907623991,0.0,0.0,0.0,0.9467278718948364,0.8633381724357605,0.8101335763931274,1.2342625856399536,1.223089575767517,-0.22566430270671844,2869.327392578125,3081.615234375,377.17242431640625,652.7442016601562,16,122,16,122,0 -50.0,9,6,121,124,122,124,122.67603898998533,123.16783414880805,0.643037497373558,0.4909967695811659,0.0805755656158551,0.0,0.0,0.0,0.8232824802398682,0.6754555702209473,0.4072394371032715,1.5877689123153687,2.0794332027435303,-0.5211251378059387,932.6954956054688,1158.416259765625,167.64625549316406,324.467529296875,123,123,123,123,0 -50.0,8,5,209,211,122,125,210.43511707054185,123.51514926423584,0.47062119879738074,0.6918685051887596,0.13957718019033916,0.0,0.0,0.0,0.8714035749435425,0.6349374055862427,1.120492935180664,2.2600760459899902,1.5373437404632568,-0.9118930697441101,780.1441650390625,972.081787109375,147.7835693359375,291.68994140625,210,124,210,124,1 -50.0,18,12,28,32,109,113,29.450508452109986,110.70154233911256,0.915215448095049,0.9881291779559387,0.08744089740461458,0.0,0.0,0.0,1.0229412317276,0.9257082343101501,0.9829065203666687,1.1019554138183594,1.0206425189971924,-0.19502708315849304,3543.401611328125,3756.772705078125,450.6411437988281,879.81201171875,29,111,29,111,1 -50.0,42,34,23,29,112,120,25.63988443055709,115.356593903113,1.1981179263202026,1.174268266346541,0.07144553404430276,0.0,0.0,0.0,1.1218854188919067,1.0553479194641113,0.7027064561843872,0.8376815915107727,0.8546950817108154,-0.10193344950675964,42160.3046875,42375.9921875,5093.25830078125,9143.6728515625,26,115,26,115,1 -50.0,38,29,20,26,120,128,21.98174004509894,125.169901285697,1.577623029681674,1.5194456756435528,-0.4735151501308277,0.0,0.0,0.0,1.4223016500473022,1.0364007949829102,-0.7547210454940796,0.6992722153663635,0.7260463237762451,0.43583786487579346,15487.984375,15868.60546875,1978.9056396484375,3965.4609375,22,125,22,125,1 -50.0,17,9,78,82,126,130,79.70801884054191,128.25510225630762,0.8869324886943151,0.855252925718716,0.06957966928594672,0.0,0.0,0.0,0.97079998254776,0.894277811050415,0.6734806895256042,1.1347236633300781,1.1767551898956299,-0.18463240563869476,3210.9853515625,3446.17529296875,457.1549987792969,887.093505859375,80,128,80,128,0 -50.0,16,10,231,234,127,130,232.51513437959267,128.58231721718406,0.8617776957290797,0.8476108545832974,0.0070656114835472295,0.0,0.0,0.0,0.9298920035362244,0.9190698266029358,0.3920697569847107,1.1604713201522827,1.1798672676086426,-0.0193471796810627,2865.9267578125,3029.0205078125,367.4806823730469,684.929931640625,233,129,232,129,0 -50.0,12,6,146,149,129,132,147.51602183926073,130.43553796282495,0.6908966519291977,0.6897889344144552,0.0016272635014389358,0.0,0.0,0.0,0.8319025039672852,0.8298336267471313,0.6213666796684265,1.4474024772644043,1.4497268199920654,-0.006829060614109039,1179.228515625,1333.822021484375,172.86854553222656,304.49139404296875,148,130,148,130,0 -50.0,16,12,249,252,128,132,250.3188317665455,129.74057473540583,0.8092820652490165,0.8578049394606895,0.04702663622633274,0.0,0.0,0.0,0.9415198564529419,0.8835311532020569,1.0235447883605957,1.239612102508545,1.1694917678833008,-0.13591618835926056,3915.816650390625,4205.6435546875,581.8317260742188,1263.1563720703125,250,130,250,130,0 -50.0,13,10,101,104,130,133,102.35441004458485,131.36733272547994,0.7495631076440594,0.7252031345357111,0.07267528437366355,0.0,0.0,0.0,0.9005953669548035,0.8146743178367615,0.7023724317550659,1.3472003936767578,1.392453670501709,-0.2700158655643463,2244.720947265625,2509.11962890625,337.4092102050781,628.26513671875,102,131,102,131,0 -50.0,9,6,208,210,130,133,208.95167702293787,131.39251105418526,0.5042180211126136,0.6375288825493362,0.08262313065374616,0.0,0.0,0.0,0.8228192329406738,0.6817004084587097,1.12481689453125,2.0263009071350098,1.6025899648666382,-0.5252133011817932,930.9444580078125,1165.052734375,166.43507385253906,313.396484375,209,131,209,131,0 -50.0,13,8,49,52,131,134,50.797359461011645,132.66535262325752,0.7226519705930343,0.7350479819790774,0.06712556281567883,0.0,0.0,0.0,0.8923346400260925,0.8132889270782471,0.8314349055290222,1.3956305980682373,1.3720943927764893,-0.2549017071723938,1934.6463623046875,2150.0166015625,304.3621826171875,594.9298706054688,51,133,51,133,1 -50.0,17,10,44,48,132,136,45.75201672805813,134.30886810780484,0.8794792749859974,0.8758249153833475,0.07013198057445802,0.0,0.0,0.0,0.973554253578186,0.8986079692840576,0.7723743915557861,1.144343614578247,1.1491183042526245,-0.18326741456985474,3199.29296875,3413.77734375,465.51678466796875,941.1021118164062,46,134,46,134,1 -50.0,62,56,170,179,124,132,172.7267253963841,127.90538271670056,1.5448767526399863,1.4331771641609734,0.0689417497546323,0.0,0.0,0.0,1.2560861110687256,1.1833434104919434,0.4449631869792938,0.6486933827400208,0.6992515325546265,-0.062409669160842896,60872.515625,61252.5,7504.91748046875,14419.712890625,173,128,173,128,1 -50.0,22,20,169,173,131,136,170.46048730070987,133.58292751636657,0.9704795995656257,1.2752903663431763,0.18166918185946823,0.0,0.0,0.0,1.1661971807479858,0.9411450624465942,1.1344105005264282,1.058648943901062,0.8056182265281677,-0.301615834236145,5804.65625,6094.796875,678.9469604492188,1304.1466064453125,170,134,170,134,1 -50.0,13,9,31,34,134,137,32.47038704797597,135.1444990210009,0.9029808671059003,0.6907373292540473,-0.06930326434521517,0.0,0.0,0.0,0.961044192314148,0.8186038136482239,-0.2892596423625946,1.116037130355835,1.4589630365371704,0.2239491492509842,1400.8173828125,1609.105224609375,197.8103485107422,399.23272705078125,32,135,32,135,0 -50.0,19,13,229,233,133,137,231.2823691025442,134.92230738217086,1.4381553184759355,1.410371073572147,0.5004942157263477,0.0,0.0,0.0,1.3874257802963257,0.9610287547111511,0.7715232968330383,0.7933067679405212,0.8089348673820496,-0.5630368590354919,1689.193603515625,1976.186767578125,141.6055450439453,291.66961669921875,232,136,232,136,0 -50.0,8,7,102,105,136,138,103.1752848012648,137.33297721647264,0.7175575917233223,0.4241220507038632,0.10331805458513998,0.0,0.0,0.0,0.8661901950836182,0.6256150603294373,0.3067682385444641,1.444275140762329,2.4435198307037354,-0.7036639451980591,744.5430908203125,964.296142578125,150.9181365966797,324.0791015625,103,137,103,137,0 -50.0,7,6,53,55,137,139,53.65203476308691,138.041193864337,0.4030631106268077,0.529759713452755,0.002442384151211785,0.0,0.0,0.0,0.7278782725334167,0.634835422039032,1.5515284538269043,2.4810702800750732,1.8877010345458984,-0.022877266630530357,579.4927978515625,785.2999877929688,115.34585571289062,204.25865173339844,54,138,54,138,0 -50.0,10,8,190,192,136,139,190.9867796130972,137.82649613882901,0.5335139969290293,0.8160309384411013,-0.03639398019541229,0.0,0.0,0.0,0.9058939814567566,0.7272558212280273,-1.4447177648544312,1.8800848722457886,1.229183316230774,0.1676989644765854,793.145263671875,982.615234375,125.57827758789062,240.51930236816406,191,138,191,138,0 -50.0,8,5,174,176,139,141,175.13456010871502,140.10772013501258,0.5056811401031178,0.5084733907902887,-0.07427083939753953,0.0,0.0,0.0,0.7624704837799072,0.6578702926635742,-0.7947959303855896,2.0208852291107178,2.0097875595092773,0.590366542339325,680.871826171875,859.41943359375,144.77578735351562,329.72698974609375,175,140,175,140,0 -50.0,17,10,27,31,141,144,28.86368374942485,142.4075992792227,0.920029218301265,0.7983367717955909,0.04955026283861441,0.0,0.0,0.0,0.9683246612548828,0.8835798501968384,0.34171563386917114,1.0905674695968628,1.256805419921875,-0.1353762149810791,3513.120849609375,3719.402099609375,500.16162109375,967.3606567382812,29,142,29,142,0 -50.0,20,10,21,25,142,146,22.930839795399187,144.0895344823549,0.9377518349400784,0.8699224305681783,0.06168052086367748,0.0,0.0,0.0,0.9870292544364929,0.9129334688186646,0.5340362191200256,1.0713768005371094,1.1549139022827148,-0.15192866325378418,5059.41845703125,5231.7255859375,772.3421020507812,1660.0743408203125,23,144,23,144,0 -50.0,24,17,143,148,142,146,145.02808190666687,143.8232494036661,1.0425088262571371,0.9689148159210181,0.03704552182145315,0.0,0.0,0.0,1.0285556316375732,0.9764717221260071,0.3943818211555481,0.9605295062065125,1.0334866046905518,-0.07344983518123627,11429.291015625,11685.994140625,1635.04736328125,3551.88330078125,145,144,145,144,0 -50.0,9,7,209,212,144,146,210.5904107200175,145.12130748165546,0.6343908942073297,0.49068307401327727,0.07321309204924509,0.0,0.0,0.0,0.8155484795570374,0.6781995296478271,0.39738360047340393,1.6039340496063232,2.073683023452759,-0.47863468527793884,977.1940307617188,1228.4892578125,172.41676330566406,329.794677734375,211,145,210,145,0 -50.0,17,13,116,120,139,142,118.20051327432608,140.6148661175294,0.9453654437490933,0.7951563125616286,0.007693799301272897,0.0,0.0,0.0,0.9725011587142944,0.8914949297904968,0.05104253068566322,1.0578752756118774,1.2577134370803833,-0.02047164924442768,5486.2705078125,5763.6728515625,787.0426025390625,1642.1025390625,118,141,118,141,1 -50.0,40,36,118,125,141,148,121.35858284470481,144.55418135575314,1.240810346805457,1.1568647202125568,0.056661158070381745,0.0,0.0,0.0,1.1266549825668335,1.0622258186340332,0.4666147232055664,0.8077315092086792,0.8663429617881775,-0.07912247627973557,37220.68359375,37364.7109375,4562.10009765625,9223.333984375,121,145,121,145,1 -50.0,29,22,238,242,140,147,240.4567881493978,144.53403468941212,1.0223265872005065,1.5507676313258543,0.13340418376954588,0.0,0.0,0.0,1.257988691329956,0.9952681064605713,1.33701753616333,0.9892659187316895,0.6521627306938171,-0.17020243406295776,13065.24609375,13118.07421875,1635.6177978515625,3479.519775390625,240,145,240,145,1 -50.0,39,32,239,247,138,149,243.9462678278684,146.0897242982483,1.3642476994640234,2.0777484391644805,0.48389967559216274,0.0,0.0,0.0,1.5238728523254395,1.058209776878357,1.1030405759811401,0.7990096807479858,0.5246289968490601,-0.37217259407043457,24805.046875,25068.724609375,3285.630126953125,6817.52685546875,244,146,244,146,1 -50.0,14,9,173,176,148,151,174.20865155923659,149.37671413094512,0.7624922884498015,0.8043815189665235,0.03797103405133351,0.0,0.0,0.0,0.9092862010002136,0.860274612903595,1.0374314785003662,1.314578890800476,1.2461204528808594,-0.12411006540060043,2179.810546875,2418.9521484375,327.2801208496094,624.2373657226562,174,149,174,149,0 -50.0,9,7,230,232,150,152,230.85896607727287,150.9637076476366,0.5648064622314607,0.5591670509841933,0.019912617674055055,0.0,0.0,0.0,0.7629534602165222,0.7361219525337219,0.7150638103485107,1.7727437019348145,1.7906224727630615,-0.12625910341739655,850.4417724609375,1049.1539306640625,155.85791015625,305.32568359375,231,151,231,151,0 -50.0,14,12,19,22,150,153,20.276513252919496,151.55209257311193,0.7647387068916445,0.8013166544557233,0.006096227674490473,0.0,0.0,0.0,0.8957152962684631,0.8739275932312012,1.4099234342575073,1.3077155351638794,1.2480218410491943,-0.01989758014678955,2300.983642578125,2517.115234375,336.15289306640625,702.5570068359375,20,152,20,152,0 -50.0,48,42,62,70,143,150,65.76975267742303,145.96697203189407,1.4895595860004818,1.3425346316111906,0.1034885974394264,0.0,0.0,0.0,1.2421706914901733,1.1353881359100342,0.47658097743988037,0.6749541163444519,0.748870313167572,-0.10405698418617249,41845.9921875,42121.296875,5333.07275390625,10997.4013671875,66,146,66,146,1 -50.0,38,34,62,70,148,153,63.96324304054647,150.39578563035062,1.9031091035084486,1.1913786789874639,0.3205446653841122,0.0,0.0,0.0,1.4234428405761719,1.0335851907730103,0.3666139245033264,0.5503984689712524,0.8792069554328918,-0.2961733341217041,25204.20703125,25452.47265625,2936.2802734375,5470.04296875,64,150,64,151,1 -50.0,23,17,89,93,149,153,90.57608935060028,150.87837807718034,1.0343561595526198,1.0132614004921838,0.00747039471008204,0.0,0.0,0.0,1.018201231956482,1.0054272413253784,0.3081274628639221,0.9668364524841309,0.9869647026062012,-0.014256242662668228,7074.64501953125,7330.12744140625,909.0516967773438,1866.5992431640625,90,151,90,151,0 -50.0,13,9,34,37,149,152,35.23954558468494,150.3329841563231,0.7378244230016038,0.7476403218855263,0.09210585487212697,0.0,0.0,0.0,0.9137663245201111,0.8065332174301147,0.812015950679779,1.3765052556991577,1.3584328889846802,-0.3391582667827606,1895.391357421875,2113.005859375,299.0359191894531,604.3773803710938,35,150,35,150,1 -50.0,16,10,112,115,152,156,113.33964543882749,154.1477535567176,0.812753328796481,0.8600871214501913,-0.02822635270497109,0.0,0.0,0.0,0.9344815015792847,0.8941950798034668,-1.134278655052185,1.2317895889282227,1.1639995574951172,0.0808497741818428,3410.67236328125,3672.533203125,511.2886962890625,1084.4530029296875,113,154,113,154,0 -50.0,26,18,103,108,153,157,105.78099706557067,155.02630002685146,1.5020116899532123,1.102809493562824,0.3645032121907086,0.0,0.0,0.0,1.3107197284698486,0.941719114780426,0.5348997116088867,0.7238324284553528,0.9858500361442566,-0.4784856140613556,8734.0302734375,9059.4365234375,993.1599731445312,1853.3935546875,106,155,106,155,0 -50.0,45,37,164,171,151,158,167.47290501063992,154.10268138194516,1.7244337020240934,1.537527579272158,-0.33672519560702874,0.0,0.0,0.0,1.4072787761688232,1.132045865058899,-0.650037407875061,0.6058074831962585,0.6794511079788208,0.2653489112854004,19724.583984375,20176.08203125,2271.752197265625,4268.12353515625,168,154,168,154,0 -50.0,15,8,120,123,159,162,121.67330585082493,160.72650888753165,0.802667358581489,0.7895896516450391,-0.030803769467596,0.0,0.0,0.0,0.9097355008125305,0.8744360208511353,-0.6808133721351624,1.2477141618728638,1.26837956905365,0.09735258668661118,2687.989013671875,2913.5986328125,402.38134765625,755.8295288085938,122,161,122,161,0 -50.0,55,43,224,233,158,164,228.13811260428062,161.00607197225477,2.0949713123890064,1.3527465242961547,-0.05028164096399301,0.0,0.0,0.0,1.4485723972320557,1.1616177558898926,-0.06733446568250656,0.4777597188949585,0.7398968935012817,0.03551669418811798,38749.97265625,38978.4375,4373.58984375,7965.8701171875,228,161,228,161,1 -50.0,13,7,244,247,161,164,245.27909971310612,162.38312731233964,0.7471597191916157,0.7455201593955456,0.07845341244050208,0.0,0.0,0.0,0.9081836938858032,0.8172406554222107,0.7801737189292908,1.353356122970581,1.3563324213027954,-0.2848357856273651,1405.09375,1574.988525390625,211.86962890625,402.385986328125,245,162,245,162,0 -50.0,11,9,36,39,162,165,37.17660784831012,163.08195853334757,0.6738370604240882,0.7135509795842392,-0.02161465369988691,0.0,0.0,0.0,0.8503206372261047,0.8150722980499268,-1.1569184064865112,1.4854817390441895,1.4028046131134033,0.08999545127153397,1069.4378662109375,1257.0887451171875,176.14810180664062,384.37127685546875,37,163,37,163,0 -50.0,7,5,109,111,164,166,110.0593672095322,165.29489061395506,0.49665581082549193,0.42912630518644623,0.02006854486478793,0.0,0.0,0.0,0.7086392641067505,0.6508551836013794,0.26813244819641113,2.0172789096832275,2.334728240966797,-0.18868035078048706,570.4808959960938,744.5750122070312,121.41209411621094,258.6505126953125,110,165,110,165,0 -50.0,10,8,235,238,164,166,236.83803757255313,165.03023865082,0.6798222676721664,0.5409179466199137,0.012084189503483556,0.0,0.0,0.0,0.8251459002494812,0.7347615361213684,0.08613421022891998,1.4715570211410522,1.8494436740875244,-0.0657496228814125,1420.4256591796875,1679.22314453125,255.72142028808594,535.8548583984375,237,165,237,165,0 -50.0,41,30,172,181,162,168,176.57617100049052,165.29414219696184,3.2823843134112707,1.590566103135929,0.11334928690156687,0.0,0.0,0.0,1.813820481300354,1.2581754922866821,0.06660177558660507,0.30540817975997925,0.6302579641342163,-0.043528903275728226,8141.8583984375,8719.5673828125,912.5098266601562,1923.00830078125,177,165,177,165,0 -50.0,5,5,38,40,167,169,39.03384200975855,167.98969817813494,0.36096762545842886,0.3528743816403027,0.0003486448484295579,0.0,0.0,0.0,0.6008182764053345,0.5940197110176086,0.0429723858833313,2.770334243774414,2.8338723182678223,-0.005474258214235306,363.5696716308594,541.8720092773438,103.5833969116211,236.55296325683594,39,168,39,168,0 -50.0,59,48,75,83,162,170,78.80674093483418,165.41015481120894,1.7823235331210636,1.6053724334116755,-0.3380639695776839,0.0,0.0,0.0,1.429439663887024,1.1594818830490112,-0.6574124693870544,0.5844081044197083,0.6488240957260132,0.24613268673419952,50136.484375,50530.875,6029.5986328125,12185.10546875,79,165,79,165,0 -50.0,8,6,133,135,168,170,133.8025112254643,168.83386720872983,0.5127611277150661,0.5089515370486397,-0.06800971831863145,0.0,0.0,0.0,0.7608500123023987,0.6654471755027771,-0.7713979482650757,1.9854143857955933,2.0002756118774414,0.5306103229522705,862.041748046875,1128.8067626953125,170.43258666992188,334.84820556640625,134,169,134,169,0 -50.0,9,8,137,139,168,170,138.01461284224456,169.07145747003057,0.564834121209558,0.5547107470126247,0.00914922231818105,0.0,0.0,0.0,0.7551347613334656,0.7411587834358215,0.5327357053756714,1.7709044218063354,1.8032231330871582,-0.058417465537786484,920.3614501953125,1133.1689453125,176.18246459960938,378.97174072265625,138,169,138,169,0 -50.0,8,6,107,109,168,171,108.06865048307881,169.48783225858077,0.46433804517792976,0.5670938051863983,0.0009610279010308087,0.0,0.0,0.0,0.7530622482299805,0.681416928768158,1.561444878578186,2.153610944747925,1.763382911682129,-0.007299251854419708,689.5531616210938,887.933837890625,129.0139923095703,258.11651611328125,108,169,108,170,0 -50.0,18,12,102,106,172,175,104.11275298813317,173.31085107755845,1.0659682389980745,0.795376233444564,0.003953985738537558,0.0,0.0,0.0,1.0324853658676147,0.8918063044548035,0.01460819412022829,0.93813157081604,1.2572897672653198,-0.009327306412160397,3370.305908203125,3590.2958984375,465.57281494140625,921.2886352539062,104,173,104,173,0 -50.0,28,19,230,235,169,174,232.41942713640222,170.98585035076016,1.133746084634824,1.047176198004741,0.05770151527797207,0.0,0.0,0.0,1.0782362222671509,1.0091228485107422,0.46359875798225403,0.8845122456550598,0.957634687423706,-0.09747681021690369,12276.4609375,12440.1171875,1628.6065673828125,3431.55615234375,232,171,232,171,1 -50.0,36,28,172,178,173,178,174.62092575217443,175.4404796965729,1.1633681314274256,1.0930556576147925,0.07643653500863579,0.0,0.0,0.0,1.101065754890442,1.0218013525009155,0.5698534846305847,0.8635407090187073,0.9190893173217773,-0.12077346444129944,32377.662109375,32645.65234375,3774.139892578125,6403.24365234375,175,175,175,175,0 -50.0,17,11,134,138,174,178,134.99621657138692,175.69296518648426,0.9123410100602558,1.1229052963060795,-0.10283917959157085,0.0,0.0,0.0,1.0792577266693115,0.9329785704612732,-1.183966040611267,1.107514500617981,0.8998363018035889,0.2028592973947525,2525.01904296875,2724.09912109375,349.9321594238281,724.4041137695312,135,176,135,176,1 -50.0,17,11,184,187,175,179,185.693119638167,176.70789625696608,0.8078679179583323,0.9269679804460003,-0.08605346224981458,0.0,0.0,0.0,0.9859345555305481,0.8733664751052856,-1.0880705118179321,1.2501885890960693,1.0895600318908691,0.2321181744337082,5964.697265625,6170.19287109375,885.7445678710938,1800.07958984375,186,177,186,177,1 -50.0,24,18,187,191,175,180,188.69599162022723,176.68761662271677,1.0662889707977286,1.6897794639035224,0.020722477931901295,0.0,0.0,0.0,1.3001797199249268,1.0322794914245605,1.5376088619232178,0.9380556344985962,0.5919342637062073,-0.02300754375755787,7251.31494140625,7359.23486328125,804.108154296875,1364.232421875,189,177,189,177,1 -50.0,10,7,163,165,178,181,163.9887516756937,179.6974770794269,0.5379010964438676,0.6728208402223785,-0.007375445015549653,0.0,0.0,0.0,0.8205015659332275,0.7331433296203613,-1.5163471698760986,1.859357237815857,1.48650324344635,0.0407644547522068,1125.860107421875,1349.1058349609375,195.28282165527344,387.5560302734375,164,180,164,180,0 -50.0,15,9,84,87,178,182,85.59937378891927,180.14265619197315,0.7828682017651682,0.8184608431243836,0.02440946120011933,0.0,0.0,0.0,0.9115221500396729,0.8777564764022827,1.100385069847107,1.2785431146621704,1.2229427099227905,-0.07626155763864517,3027.99365234375,3292.3515625,455.1092224121094,896.7258911132812,86,180,86,180,0 -50.0,25,16,148,152,172,177,149.8584812086031,174.63492152421176,1.0110816439896952,1.0340141167343209,0.038395076840501474,0.0,0.0,0.0,1.0308338403701782,0.9911999106407166,0.9305016398429871,0.9904363751411438,0.9684703946113586,-0.0735538899898529,10297.9111328125,10476.6171875,1389.514404296875,2755.148193359375,150,175,150,175,1 -50.0,48,38,153,159,174,182,155.76368044444834,176.49130912981622,1.2168205106288479,1.9967009114072987,0.18529413401960415,0.0,0.0,0.0,1.4277558326721191,1.083990216255188,1.3489962816238403,0.8335937261581421,0.508004903793335,-0.15471522510051727,27861.62109375,28135.462890625,3327.5458984375,6231.3037109375,156,176,156,176,1 -50.0,8,6,53,56,182,184,54.49669440437775,182.90967651920593,0.5468242576528874,0.4726363841106507,0.0012348002442277295,0.0,0.0,0.0,0.7394895553588867,0.6874706149101257,0.01663808897137642,1.8287519216537476,2.1158039569854736,-0.009555520489811897,710.045166015625,913.3258056640625,133.73495483398438,277.3197021484375,54,183,54,183,0 -50.0,13,9,238,241,178,182,239.0922177767758,179.94631540276814,0.7784821553605119,0.8088243681077891,0.15653666952573664,0.0,0.0,0.0,0.9751530289649963,0.7977362871170044,0.8337059020996094,1.3365648984909058,1.286424994468689,-0.517346978187561,1652.2779541015625,1829.42333984375,263.2916259765625,578.579345703125,239,180,239,180,1 -50.0,29,20,207,213,183,188,209.70425475703345,185.62649290422357,1.4527983860579248,1.23094734215295,0.34174983876502374,0.0,0.0,0.0,1.3042906522750854,0.9912474751472473,0.6284716725349426,0.7364215850830078,0.8691452741622925,-0.4089077413082123,8802.1669921875,9069.720703125,900.4190063476562,1582.0926513671875,209,185,209,186,1 -50.0,10,8,13,15,186,189,13.978522485048114,187.90636248802048,0.6047544255843542,0.80135562030787,0.17845614745431848,0.0,0.0,0.0,0.9522573351860046,0.7066229581832886,1.0371416807174683,1.769869089126587,1.335657000541687,-0.788274347782135,861.6199340820312,1052.0958251953125,142.73741149902344,291.36529541015625,14,188,14,188,0 -50.0,22,19,22,26,184,189,23.817677903005745,185.995988142306,1.0568258604459837,1.451895798373612,-0.3911891475895093,0.0,0.0,0.0,1.3009976148605347,0.9033973813056946,-1.0192021131515503,1.0510534048080444,0.7650551795959473,0.5663776397705078,4464.51416015625,4803.26025390625,563.3185424804688,1166.2139892578125,24,186,24,186,0 -50.0,13,8,6,9,187,190,7.65793214195172,188.76683972410996,0.7498894001870755,0.7240461550778567,0.06961407586924517,0.0,0.0,0.0,0.8987607955932617,0.8161890506744385,0.6936335563659668,1.3455395698547363,1.3935656547546387,-0.258736252784729,1811.42236328125,2015.57470703125,279.0719909667969,518.5321655273438,8,189,8,189,0 -50.0,9,7,110,112,189,191,111.0047221928821,189.94239418562847,0.5651898521113103,0.5572996669647163,0.008035228328013733,0.0,0.0,0.0,0.7551133632659912,0.7431643605232239,0.5571975708007812,1.7696797847747803,1.7947345972061157,-0.05103100463747978,864.464599609375,1054.4056396484375,165.51849365234375,364.77972412109375,111,190,111,190,0 -50.0,17,10,245,249,187,191,247.09710366023418,189.1402084356898,0.8791389956559712,0.8527257660711367,0.018051807882478066,0.0,0.0,0.0,0.9424963593482971,0.9184581637382507,0.46958938241004944,1.1379711627960205,1.173219919204712,-0.04818064346909523,2773.291748046875,2990.623779296875,421.8832702636719,898.6165771484375,247,189,247,189,0 -50.0,19,12,169,173,188,192,170.82744535269882,189.77049242294424,0.9152826170433612,0.916462714180807,-0.05338235905658317,0.0,0.0,0.0,0.9845091700553894,0.9287018179893494,-0.7909245491027832,1.0962830781936646,1.0948714017868042,0.1277131587266922,3633.08349609375,3804.6220703125,518.958251953125,1038.780517578125,171,190,171,190,0 -50.0,18,10,118,122,190,194,120.09458302314914,191.84407145173344,0.9089986943846053,0.8136594739575496,0.06680950763264093,0.0,0.0,0.0,0.9712886214256287,0.8827551007270813,0.4755285680294037,1.1067910194396973,1.2364773750305176,-0.18175701797008514,3297.876708984375,3503.11328125,514.9900512695312,1147.740234375,120,192,120,192,0 -50.0,10,7,146,149,192,194,147.76112887076133,192.96025609506114,0.6752738284725206,0.5294421282431258,0.0069483817750417565,0.0,0.0,0.0,0.8219514489173889,0.7274007201194763,0.04750313609838486,1.4810807704925537,1.889035701751709,-0.038875315338373184,1161.2335205078125,1406.512451171875,209.2403106689453,414.76483154296875,148,193,148,193,0 -50.0,18,13,45,49,193,196,46.91855416810206,194.51114176563675,0.9912249745529635,0.8222142739861225,0.11662950854447818,0.0,0.0,0.0,1.0250589847564697,0.8733230829238892,0.4718875288963318,1.0259764194488525,1.2368714809417725,-0.2910655438899994,4582.39208984375,4867.6982421875,609.2089233398438,1095.4195556640625,47,195,47,194,0 -50.0,12,7,64,67,194,197,65.59144830567396,195.4432378140081,0.6872017630974021,0.688044629417059,0.0022914124503543576,0.0,0.0,0.0,0.8306341171264648,0.8278244733810425,0.8763411045074463,1.4551929235458374,1.453410267829895,-0.009692531079053879,1343.12744140625,1529.4539794921875,203.341064453125,362.5701904296875,66,195,66,195,0 -50.0,11,8,93,96,194,197,94.89456356712336,195.15176723981506,0.6479547145564148,0.650909640389435,0.021817893744184857,0.0,0.0,0.0,0.819329023361206,0.7921895980834961,0.8192055225372314,1.5450615882873535,1.538047432899475,-0.10357809066772461,1661.671630859375,1960.0050048828125,289.3518981933594,589.7023315429688,95,195,95,195,0 -50.0,8,6,203,205,197,199,203.84324205590897,197.83142995923376,0.5229029318964928,0.5106217030056324,-0.07389845920201699,0.0,0.0,0.0,0.7687102556228638,0.6652888059616089,-0.7439457178115845,1.952331304550171,1.9992878437042236,0.5650926232337952,694.5953979492188,890.9127807617188,137.06268310546875,275.66729736328125,204,198,204,198,0 -50.0,7,7,20,22,198,200,20.966309549129434,198.71312366399218,0.4968230656637175,0.4191311693935237,0.009265624898403102,0.0,0.0,0.0,0.7056293487548828,0.6465612053871155,0.11707364767789841,2.0136191844940186,2.3868720531463623,-0.08902911841869354,693.3228759765625,949.3165283203125,153.49948120117188,333.41986083984375,21,199,21,199,0 -50.0,5,5,76,78,198,200,77.04691111138324,199.05021583186894,0.35418729305809604,0.35546305600737416,-0.0023556586145419,0.0,0.0,0.0,0.5977170467376709,0.5936200022697449,-0.9176207184791565,2.8234894275665283,2.8133559226989746,0.03742260858416557,348.89251708984375,530.7075805664062,99.65325927734375,216.13502502441406,77,199,77,199,0 -50.0,25,20,102,106,190,195,103.83398445213459,192.31433903473285,1.0296177690281034,1.0561264858366055,0.024035038294214495,0.0,0.0,0.0,1.0345624685287476,1.0076828002929688,1.0373798608779907,0.9717504382133484,0.947359561920166,-0.0442296639084816,10008.08984375,10241.05859375,1348.878173828125,2728.555419921875,104,192,104,192,1 -50.0,7,6,216,218,198,200,216.66493616522118,198.93412688729023,0.41627330916208477,0.5163652301316835,0.00802039861117454,0.0,0.0,0.0,0.7190297842025757,0.644697368144989,1.4913415908813477,2.402987003326416,1.937193512916565,-0.07464838027954102,527.8672485351562,712.4092407226562,105.71427154541016,187.8160858154297,217,199,217,199,0 -50.0,37,28,162,169,194,199,165.44042576368298,196.47568902746,1.296971322393631,1.1722638279645157,0.10575503979916512,0.0,0.0,0.0,1.1650691032409668,1.0544425249099731,0.5190274715423584,0.7767408490180969,0.8593719005584717,-0.14014635980129242,20338.650390625,20518.216796875,2265.285888671875,4246.6591796875,165,197,165,197,1 -50.0,18,12,167,171,200,204,169.50296007052253,201.80940498473882,1.184938548272756,1.0683816845855398,-0.2351125818900135,0.0,0.0,0.0,1.169994831085205,0.9404426217079163,-0.6639095544815063,0.8824577927589417,0.9787309765815735,0.3883947730064392,2288.20703125,2507.73583984375,294.335205078125,562.5618286132812,170,202,170,202,1 -50.0,18,15,209,213,200,204,210.76394001625877,201.56595859685655,0.9994990407219286,1.051858055237957,0.3012031065281513,0.0,0.0,0.0,1.152396321296692,0.8504939079284668,0.8287474513053894,1.0949921607971191,1.0404860973358154,-0.6271094083786011,3016.399658203125,3269.308837890625,377.0010986328125,665.1902465820312,211,201,211,201,0 -50.0,15,12,99,102,203,206,100.37381683309358,204.64699362187565,0.8343868215656973,0.804616856285393,0.05697847410525014,0.0,0.0,0.0,0.9372259378433228,0.872130274772644,0.6576341986656189,1.2043086290359497,1.2488667964935303,-0.17056483030319214,3144.90478515625,3402.995849609375,447.57427978515625,924.7835693359375,100,205,100,205,0 -50.0,49,37,174,185,199,206,180.11362406869208,202.70313341279703,4.464101106320086,3.4304710755417176,-0.8696774924719008,0.0,0.0,0.0,2.2268669605255127,1.713369607925415,-0.5173038244247437,0.23564761877059937,0.3066502511501312,0.11948063969612122,5474.83251953125,6065.12890625,314.1866455078125,615.5050659179688,179,203,179,203,0 -50.0,10,7,2,4,204,207,2.835397210004157,205.4957964723859,0.5101720242870798,0.7295767436418785,0.012914211984057289,0.0,0.0,0.0,0.854595959186554,0.7137327790260315,1.512205719947815,1.9610018730163574,1.3712722063064575,-0.06942325085401535,1075.0560302734375,1307.9603271484375,178.67979431152344,329.07232666015625,3,206,3,206,0 -50.0,9,6,128,130,202,205,129.3098956937452,203.30746661351344,0.5445977839770588,0.6912831634931469,-0.11720107111286504,0.0,0.0,0.0,0.8695966601371765,0.6925911903381348,-1.0649800300598145,1.9057515859603882,1.5013645887374878,0.646207332611084,865.0712280273438,992.515869140625,150.97021484375,312.1363525390625,129,203,129,203,1 -50.0,22,18,123,128,203,207,125.34446276680896,204.86024884580655,1.2943988205223,0.9934364505882458,0.2735442041761438,0.0,0.0,0.0,1.2066984176635742,0.9119836091995239,0.5339318513870239,0.820292055606842,1.0688002109527588,-0.45173725485801697,4884.9013671875,5168.6572265625,617.4840698242188,1305.510986328125,125,205,125,205,1 -50.0,19,13,215,219,205,208,217.00991382973046,206.4650130054529,0.9926374041881694,0.8334243024124954,0.05719114952681181,0.0,0.0,0.0,1.0055105686187744,0.902779221534729,0.3114917278289795,1.011415958404541,1.2046316862106323,-0.13881056010723114,5214.67529296875,5465.08154296875,704.6378173828125,1307.369873046875,217,206,217,206,0 -50.0,7,7,187,189,208,210,187.689674375908,208.96663266722803,0.4411867390774143,0.5005582440680308,-0.005621363335852725,0.0,0.0,0.0,0.7078741192817688,0.6638216376304626,-1.4772231578826904,2.2669382095336914,1.9980554580688477,0.050916288048028946,539.6389770507812,708.6959228515625,108.11297607421875,188.4962921142578,188,209,188,209,0 -50.0,7,6,77,79,209,211,77.93044931572976,209.63493598437447,0.5108694792172566,0.39706283934836933,0.01183134356525406,0.0,0.0,0.0,0.7156021595001221,0.6291628479957581,0.10249965637922287,1.958798885345459,2.5202322006225586,-0.11673327535390854,654.5709838867188,900.8104248046875,134.97805786132812,262.88433837890625,78,210,78,210,0 -50.0,14,9,107,110,207,211,108.37095260102166,208.9842249587497,0.8010221790388021,0.7180753633235288,0.0162366524094808,0.0,0.0,0.0,0.8967090845108032,0.8455828428268433,0.1865767389535904,1.2489773035049438,1.3932501077651978,-0.05648212507367134,2491.253173828125,2749.88037109375,395.33514404296875,855.1337890625,108,209,108,209,0 -50.0,7,6,235,237,209,211,235.73655499302026,209.9375000803129,0.4365489441622251,0.49431414685596886,0.014324809840091213,0.0,0.0,0.0,0.7054582238197327,0.6581730246543884,1.3405884504318237,2.292874336242676,2.024930477142334,-0.13289114832878113,569.975341796875,756.1456298828125,122.69012451171875,256.0504150390625,236,210,236,210,0 -50.0,19,13,36,40,202,206,38.04198826118003,203.89204825296744,1.0426829425488044,0.9751300442898208,0.13756890967116497,0.0,0.0,0.0,1.072642207145691,0.9312635660171509,0.6650174856185913,0.977254331111908,1.0449544191360474,-0.2757371962070465,3607.593505859375,3755.202880859375,504.8069152832031,1084.029296875,38,204,38,204,1 -50.0,10,8,228,231,210,212,229.80816932156358,210.9271445125786,0.6804132805392822,0.5379349706913027,-0.010045700685879178,0.0,0.0,0.0,0.8252987861633301,0.7329598665237427,-0.07004503160715103,1.4701002836227417,1.859473466873169,0.05490696430206299,1202.4737548828125,1440.5914306640625,212.96115112304688,418.80804443359375,230,211,230,211,0 -50.0,5,4,143,144,211,213,143.42703041032613,211.6923220001216,0.24467543898282634,0.4300351951436282,-0.06830612140445552,0.0,0.0,0.0,0.6726714968681335,0.47140610218048096,-1.2532280683517456,4.276688098907471,2.433290481567383,1.358604907989502,482.78070068359375,747.2432861328125,119.7115707397461,245.49952697753906,143,212,143,212,0 -50.0,9,8,251,253,211,213,252.0026481973926,212.0882940830594,0.5675715199077103,0.5635042467976945,0.009052657229607242,0.0,0.0,0.0,0.7581663131713867,0.7458281517028809,0.674909770488739,1.7623441219329834,1.7750643491744995,-0.05662387236952782,1083.080078125,1317.7799072265625,201.5407257080078,421.544189453125,252,212,252,212,0 -50.0,19,14,87,91,212,215,88.92678845604753,213.38269208691628,1.0149308360446225,0.8238484615541981,-0.017535275442758458,0.0,0.0,0.0,1.0082294940948486,0.9067814350128174,-0.0907580628991127,0.9856512546539307,1.2142620086669922,0.041958361864089966,4824.1806640625,5037.13525390625,677.5173950195312,1335.730712890625,89,213,89,213,0 -50.0,12,7,108,111,215,217,109.50621700217404,215.99923159853753,0.8429751455765198,0.5623761056401064,0.011194506322479647,0.0,0.0,0.0,0.918379545211792,0.7496200203895569,0.03981068730354309,1.1865882873535156,1.778639554977417,-0.04723981022834778,1371.947998046875,1553.1298828125,214.92381286621094,446.02239990234375,109,216,109,216,0 -50.0,16,14,120,123,208,213,121.31514641574361,211.67529754698563,0.805884564720607,1.143314417596347,0.17566291309549698,0.0,0.0,0.0,1.103703260421753,0.8550076484680176,1.1680108308792114,1.283869981765747,0.9049575328826904,-0.3945167362689972,3371.271484375,3729.02978515625,466.4741516113281,963.2971801757812,121,212,121,212,1 -50.0,20,12,122,126,213,218,123.93374616518949,215.77493170986426,0.9626450884042814,1.0258051628203226,0.10423631608370076,0.0,0.0,0.0,1.050304889678955,0.9409091472625732,0.9324858784675598,1.0503615140914917,0.9856894016265869,-0.2134631723165512,4270.26708984375,4379.576171875,601.0850830078125,1213.555419921875,124,216,124,216,1 -50.0,5,5,186,188,217,219,186.9866028752779,218.03454507524276,0.3649537683683568,0.3517686537393574,0.0004628046815615683,0.0,0.0,0.0,0.6041274666786194,0.5930871963500977,0.035043053328990936,2.7400777339935303,2.8427822589874268,-0.007209970150142908,356.4978942871094,530.68017578125,100.49844360351562,217.3298797607422,187,218,187,218,0 -50.0,21,15,93,97,215,220,94.77395297848612,216.63305812251676,1.013461749883584,1.0385914076093075,-0.12149126431621049,0.0,0.0,0.0,1.071524977684021,0.9507299065589905,-0.8369258046150208,1.0007505416870117,0.9765364527702332,0.23412950336933136,5483.0625,5769.833984375,729.6310424804688,1373.0396728515625,95,217,95,217,0 -50.0,5,5,235,237,219,221,236.04435285014273,219.9949480516677,0.35722781233849754,0.3600660038553124,0.00022406830731092064,0.0,0.0,0.0,0.6000696420669556,0.5976706743240356,1.4924951791763306,2.799335241317749,2.7772696018218994,-0.003484040731564164,367.5738525390625,536.5534057617188,103.18293762207031,233.12107849121094,236,220,236,220,0 -50.0,10,7,157,159,219,222,158.03851270728688,220.74422688083882,0.5373452149349234,0.6857303125627405,0.0014048210462720423,0.0,0.0,0.0,0.8280963897705078,0.7330292463302612,1.5613300800323486,1.861011028289795,1.4583070278167725,-0.007625118363648653,1238.56494140625,1452.4942626953125,216.2947998046875,456.7906494140625,158,221,158,221,0 -50.0,10,7,1,3,220,223,1.9912663180969925,221.80524482596533,0.542789714533462,0.6825663499455938,-0.0025251115422859627,0.0,0.0,0.0,0.8262033462524414,0.7367116808891296,-1.552738904953003,1.8423658609390259,1.465084195137024,0.013631434179842472,1519.9881591796875,1806.01513671875,271.1833801269531,572.5770874023438,2,222,2,222,0 -50.0,16,11,61,64,219,223,62.36026220976968,220.9967065782505,0.9044479880855194,1.0004560032183392,0.20334759989166828,0.0,0.0,0.0,1.077677607536316,0.8622732162475586,0.9013104438781738,1.1585919857025146,1.0474085807800293,-0.4709790349006653,2098.374267578125,2311.847412109375,263.837158203125,439.05010986328125,62,221,62,221,0 -50.0,16,12,121,125,220,223,123.21595867056476,221.34248638486136,0.8911160474974498,0.8038730495106483,-0.0227589019418879,0.0,0.0,0.0,0.9469404220581055,0.8934723734855652,-0.24044236540794373,1.1230002641677856,1.2448776960372925,0.06358778476715088,3294.632080078125,3560.931640625,475.1404724121094,931.3710327148438,123,221,123,221,0 -50.0,14,13,115,118,220,223,116.08406547977633,221.3131352449848,0.7915366974128624,0.9209114679812624,0.033937988889727766,0.0,0.0,0.0,0.9639884233474731,0.8849714398384094,1.3292115926742554,1.265364646911621,1.087599277496338,-0.09326397627592087,2397.74951171875,2632.885498046875,331.2652587890625,665.4586791992188,116,221,116,221,1 -50.0,14,10,116,120,223,226,118.09049081157916,224.6774321356568,0.8780960378024751,0.7445644239191171,-0.008336831736146522,0.0,0.0,0.0,0.9373443722724915,0.8625809550285339,-0.06211191415786743,1.138948678970337,1.3432098627090454,0.025505444034934044,2202.08154296875,2368.9072265625,325.9726257324219,691.3895263671875,118,225,118,225,1 -50.0,17,12,110,114,221,224,111.53634022818649,222.48025902885772,1.0857189031273204,0.8361771481082698,0.0945390810194291,0.0,0.0,0.0,1.0571140050888062,0.8968868255615234,0.3242059350013733,0.9302064180374146,1.2078094482421875,-0.21034026145935059,2336.988525390625,2456.72998046875,278.6284484863281,487.380126953125,111,222,111,222,1 -50.0,6,5,149,151,224,226,149.82525810816887,225.18717412262896,0.41425795319036995,0.41239627176779803,-0.10174041532649669,0.0,0.0,0.0,0.7176850438117981,0.5581957101821899,-0.7808237075805664,2.569650173187256,2.5812504291534424,1.2678934335708618,461.5179443359375,648.6360473632812,111.79090881347656,237.9472198486328,150,225,150,225,0 -50.0,16,12,248,252,223,226,250.07769574496453,224.53007903363476,0.8844783120397404,0.7928970117986727,0.019462282518471152,0.0,0.0,0.0,0.9425724148750305,0.8882188200950623,0.20094694197177887,1.1312209367752075,1.2618794441223145,-0.05553342029452324,3177.04345703125,3414.986328125,448.5862731933594,897.7916259765625,250,225,250,225,0 -50.0,37,29,134,141,221,227,137.8229211780975,224.58032322821686,2.2468101497142854,2.4539568356094126,-0.44173645940698414,0.0,0.0,0.0,1.6745446920394897,1.3771953582763672,-0.9005523324012756,0.46140503883361816,0.422456294298172,0.1661149263381958,6954.470703125,7399.89111328125,552.9661865234375,1104.031982421875,137,226,137,226,0 -50.0,16,10,194,197,221,225,195.5996735643267,223.1922749878649,0.8173595203157076,0.9467169048401924,-0.03843534239788893,0.0,0.0,0.0,0.9784044027328491,0.8982211351394653,-1.3027057647705078,1.2257919311523438,1.058302402496338,0.09953077882528305,3164.4296875,3242.19921875,436.3905029296875,837.5336303710938,196,223,196,223,1 -50.0,15,12,191,195,224,227,192.99752409737326,225.73472377546642,0.8748890127559461,0.7572661319397787,0.13973771462077966,0.0,0.0,0.0,0.9837108254432678,0.815149188041687,0.5862144231796265,1.1777129173278809,1.3606420755386353,-0.434644877910614,3027.249267578125,3303.182861328125,458.07568359375,943.2509155273438,193,226,193,226,1 -50.0,18,10,25,29,226,230,27.19110187546641,227.8724793045787,0.8506886015989634,0.8839202164319091,0.04766954861522521,0.0,0.0,0.0,0.9580118656158447,0.903782069683075,0.9530948996543884,1.1790814399719238,1.1347531080245972,-0.12717501819133759,3682.443359375,3910.7060546875,564.5975341796875,1249.12890625,27,228,27,228,0 -50.0,7,5,69,71,228,230,70.29895656612594,228.91433860010588,0.4091299575244325,0.495443858218516,-0.013140517488329673,0.0,0.0,0.0,0.7052659392356873,0.6381016969680786,-1.423014521598816,2.4462950229644775,2.020112991333008,0.12976478040218353,588.8306274414062,789.2865600585938,129.55850219726562,288.837158203125,70,229,70,229,0 -50.0,14,11,113,116,228,231,114.59797681892248,229.45309338826024,0.8243305274147499,0.9507353763954169,-0.24491055767972858,0.0,0.0,0.0,1.0679265260696411,0.7966170310974121,-0.9116747379302979,1.3136439323425293,1.1389886140823364,0.6767924427986145,1693.531005859375,1959.22998046875,223.81930541992188,427.70556640625,115,229,115,229,0 -50.0,9,8,183,185,229,231,183.9476740784029,230.06449658204212,0.5597550030685163,0.5555740665945901,0.013145418934731534,0.0,0.0,0.0,0.7556289434432983,0.7378034591674805,0.7065452933311462,1.7874890565872192,1.800940752029419,-0.08458743989467621,1134.3428955078125,1404.1212158203125,218.36746215820312,469.42926025390625,184,230,184,230,0 -50.0,7,5,137,139,230,232,138.3014265921217,231.03466361184283,0.41329456480948146,0.4978998298300261,0.009760954150401124,0.0,0.0,0.0,0.706407368183136,0.6420148015022278,1.4574103355407715,2.4207024574279785,2.009366512298584,-0.09491213411092758,646.4238891601562,864.9373168945312,142.15086364746094,314.7203369140625,138,231,138,231,0 -50.0,7,5,126,128,233,235,127.1013149631741,233.6474244709559,0.5058534816784375,0.406688905796656,-0.0038555665669022243,0.0,0.0,0.0,0.711338996887207,0.637604296207428,-0.03880240023136139,1.9769998788833618,2.459059715270996,0.037485431879758835,605.7955322265625,801.2269897460938,124.23033142089844,255.1316680908203,127,234,127,234,0 -50.0,14,10,171,174,232,235,172.14911700325973,233.4466766718806,0.7445256687057726,0.7909880083804643,0.016551109136242692,0.0,0.0,0.0,0.8923457860946655,0.8597864508628845,1.2612789869308472,1.3437621593475342,1.2648299932479858,-0.05623537302017212,2245.0859375,2487.8505859375,336.30462646484375,642.146240234375,172,233,172,233,0 -50.0,14,8,155,158,234,237,156.4854397580585,235.8171653786979,0.8096159731737251,0.7304101343135003,0.015495980100760143,0.0,0.0,0.0,0.9014098644256592,0.852928102016449,0.1864849478006363,1.2356553077697754,1.3696500062942505,-0.05242996662855148,2202.35791015625,2399.305908203125,324.8695373535156,673.0716552734375,156,236,156,236,0 -50.0,11,8,59,62,237,240,60.7987773354741,238.1607095663459,0.6590691761515428,0.6335027592932336,0.023109644314096123,0.0,0.0,0.0,0.8201801776885986,0.7873222827911377,0.5327671766281128,1.5192346572875977,1.5805467367172241,-0.11084078997373581,1514.42041015625,1775.4993896484375,259.7996826171875,515.2501220703125,61,238,61,238,0 -50.0,28,21,229,235,235,240,231.5148681649154,237.78926455998823,2.00328408725339,1.525708013690191,-0.04164231197528423,0.0,0.0,0.0,1.4166467189788818,1.2337359189987183,-0.08632700145244598,0.4994637072086334,0.6558054685592651,0.027264486998319626,4018.336181640625,4399.27978515625,390.0617370605469,724.1670532226562,231,238,231,238,0 -50.0,10,8,83,86,239,241,84.2196771254686,240.0347101745618,0.6919828427706265,0.5412273018653437,0.025010475013871547,0.0,0.0,0.0,0.8342803716659546,0.7329300045967102,0.16018573939800262,1.4475401639938354,1.8507436513900757,-0.13378359377384186,1249.6483154296875,1509.4044189453125,218.98480224609375,439.7369384765625,84,240,84,240,0 -50.0,20,16,75,80,238,242,77.64000763574423,239.65495116776992,1.2242302694730052,0.896885553552373,-0.11807822928471179,0.0,0.0,0.0,1.1235556602478027,0.926681399345398,-0.3124822676181793,0.8273455500602722,1.1293095350265503,0.2178460657596588,4860.03515625,5226.072265625,549.8914794921875,871.4837036132812,78,240,78,240,0 -50.0,56,54,213,220,233,240,216.08647174829497,236.06659238211859,1.4732359652995974,1.4567142624965257,0.010012884700511648,0.0,0.0,0.0,1.215712070465088,1.2049872875213623,0.44049155712127686,0.6788095831871033,0.6865084767341614,-0.00933174416422844,43196.375,43498.77734375,5535.38427734375,11952.30859375,216,236,216,236,1 -50.0,14,10,210,213,239,242,211.7408908432123,240.23622989715074,0.8671696784663396,0.8049483105299036,-0.07752300366386855,0.0,0.0,0.0,0.9589533805847168,0.8674827814102173,-0.5945810079574585,1.163191556930542,1.2531046867370605,0.2240494340658188,2206.16357421875,2416.489990234375,286.67425537109375,460.78271484375,212,240,211,240,1 -50.0,26,20,244,248,238,243,245.64056334988587,240.62451198026787,1.0186330935278156,1.9553871437663872,-0.22407280960314946,0.0,0.0,0.0,1.4164133071899414,0.9837650656700134,-1.3476858139038086,1.007093906402588,0.5246322751045227,0.23081094026565552,5139.09619140625,5427.12353515625,428.8789978027344,647.601806640625,246,241,245,242,0 -50.0,13,9,161,164,241,244,162.5877729977956,242.316740569885,0.7299322113886935,0.8190000691926296,-0.06857966337984722,0.0,0.0,0.0,0.925330638885498,0.8322833180427551,-1.0733660459518433,1.3808537721633911,1.2306832075119019,0.23125392198562622,1429.7489013671875,1619.600830078125,198.05044555664062,377.82958984375,163,242,162,242,0 -50.0,96,80,94,105,233,246,97.32306698208778,238.66591747103672,2.0185927288932444,1.7990373549290624,0.08068271998298826,0.0,0.0,0.0,1.4300535917282104,1.3313815593719482,0.3169044256210327,0.49628424644470215,0.5568510293960571,-0.044514432549476624,86381.390625,86969.203125,10282.869140625,20853.79296875,97,239,97,239,0 -50.0,16,11,39,44,241,247,42.17169484777176,242.9244469351536,1.047181499948028,1.6843041386298019,-0.17446793947540673,0.0,0.0,0.0,1.3148958683013916,1.001266360282898,-1.3202682733535767,0.9717140793800354,0.6041432619094849,0.2013091892004013,1777.5245361328125,1937.2750244140625,237.6128387451172,510.8245849609375,42,243,42,243,1 -50.0,26,17,51,56,245,249,53.07505788222462,246.83379448276474,1.0950303172036069,0.9821606774876521,0.04583917842908969,0.0,0.0,0.0,1.054182767868042,0.9827969074249268,0.34108296036720276,0.9150043725967407,1.0201565027236938,-0.0854097530245781,13072.23046875,13314.404296875,1853.791748046875,4038.5244140625,53,247,53,247,0 -50.0,14,10,205,208,243,246,206.35955545201048,244.16578200151156,0.8203532767617552,0.7565529059714193,0.031246131782384445,0.0,0.0,0.0,0.912746787071228,0.8624381422996521,0.3875204026699066,1.2209075689315796,1.3238672018051147,-0.10084857046604156,1965.2021484375,2147.555419921875,293.4020690917969,610.0169067382812,206,244,206,244,1 -50.0,10,6,209,211,246,249,209.88565927107908,247.62211023371262,0.5165210500123121,0.7683858352151889,0.02002075174146567,0.0,0.0,0.0,0.8774778246879578,0.7175928950309753,1.4919660091400146,1.9379867315292358,1.3027452230453491,-0.10099080204963684,963.1103515625,1158.166015625,154.06089782714844,275.68267822265625,210,248,210,248,1 -50.0,16,10,104,107,246,250,105.31235347643928,247.8140834711784,0.798675333671873,0.8257590992102917,0.03504775140701444,0.0,0.0,0.0,0.9218406677246094,0.8801387548446655,0.9697548747062683,1.2544095516204834,1.2132666110992432,-0.10648198425769806,3441.29296875,3724.649169921875,534.100830078125,1176.4752197265625,105,248,105,248,0 -50.0,19,15,135,139,242,246,136.9750912245973,243.48428679784934,0.9847091328104618,0.8773491282780306,0.13793687049669634,0.0,0.0,0.0,1.0387699604034424,0.8848814368247986,0.5998332500457764,1.0383970737457275,1.1654644012451172,-0.3265136778354645,5222.185546875,5507.0986328125,705.94189453125,1306.1685791015625,137,243,137,244,1 -50.0,15,11,139,142,246,250,140.77300917908397,248.3324925286055,0.7822374277276385,1.0733764807823807,0.21951401838121765,0.0,0.0,0.0,1.0914219617843628,0.8151147365570068,1.0781782865524292,1.3562171459197998,0.9883612990379333,-0.5547143220901489,1715.2769775390625,1903.6475830078125,222.55380249023438,391.58184814453125,141,248,141,248,1 -50.0,38,30,58,63,243,251,59.86720635570958,246.00086614911558,1.175693792392885,1.5662972135111506,-0.06246022805872897,0.0,0.0,0.0,1.255405068397522,1.0797911882400513,-1.4160292148590088,0.8523674011230469,0.6398038864135742,0.06798078864812851,19954.83984375,20369.130859375,2633.992919921875,5379.02294921875,60,246,60,246,0 -50.0,34,26,81,87,246,251,83.40954964225254,248.68072137159493,1.1536157663400237,1.062667329134114,0.07010728043579117,0.0,0.0,0.0,1.0916526317596436,1.012214183807373,0.49768972396850586,0.8703291416168213,0.9448162913322449,-0.11483633518218994,34257.93359375,34548.69921875,4436.60693359375,9266.9912109375,83,249,83,249,0 -50.0,27,15,183,188,247,252,185.16649493926403,249.61956191537868,1.0693461515068599,1.0142130365971536,0.048196947996430595,0.0,0.0,0.0,1.0475224256515503,0.9931042790412903,0.5256261825561523,0.9371581673622131,0.9881024956703186,-0.08907036483287811,10553.2890625,10724.6279296875,1421.6524658203125,2989.731689453125,185,250,185,250,0 -50.0,20,14,197,201,248,252,198.59825285846713,250.33767840536768,0.9612092709991842,0.9435766514272803,0.04695749821817152,0.0,0.0,0.0,1.000085473060608,0.9511125087738037,0.6926030516624451,1.0428916215896606,1.0623801946640015,-0.10379990190267563,5730.58056640625,5951.5947265625,714.6837158203125,1244.071044921875,199,250,198,250,0 -50.0,9,8,237,239,252,254,237.9299311472982,253.03783435651596,0.5603300375435427,0.5620730516402843,0.007845728960167553,0.0,0.0,0.0,0.7543842196464539,0.7438464760780334,0.8407116532325745,1.7850114107131958,1.7794759273529053,-0.04983236640691757,1102.015869140625,1359.2587890625,209.3085174560547,445.35430908203125,238,253,238,253,0 -50.0,38,32,7,14,251,255,9.924784124604642,254.0122693853021,1.3955173435618917,0.801592019732615,0.021055797534964782,0.0,0.0,0.0,1.1816357374191284,0.8949002623558044,0.035392697900533676,0.7168642282485962,1.2480120658874512,-0.03766042739152908,45060.33203125,49689.59765625,6509.44580078125,12547.8173828125,10,254,10,254,2 -50.0,10,8,78,81,253,255,79.75986568838789,253.60854690072088,0.9174463652396732,0.5023744567833865,-0.059515371243072046,0.0,0.0,0.0,0.9621909260749817,0.702858030796051,-0.13963834941387177,1.0984234809875488,2.005963087081909,0.2602563798427582,1003.5051879882812,1170.082275390625,156.6302032470703,283.813232421875,80,254,80,254,1 -50.0,75,71,153,162,246,255,156.8351087900011,249.40541322150372,1.5727847038860183,1.4765197019588001,0.028985448478703546,0.0,0.0,0.0,1.2573139667510986,1.2118027210235596,0.27101820707321167,0.6360450387001038,0.6775134205818176,-0.024972306564450264,88483.1484375,88793.5,10207.31640625,18594.044921875,157,249,157,249,1 -50.0,32,23,146,152,250,255,148.99681298405,252.40764270971644,1.3140199525676621,1.173270158624387,0.16261069591948107,0.0,0.0,0.0,1.1919862031936646,1.0326950550079346,0.5811765789985657,0.7743037939071655,0.8671921491622925,-0.21463100612163544,11393.59765625,11602.412109375,1354.80322265625,2561.89111328125,149,252,149,253,3 -50.0,46,38,165,173,249,255,168.05291274565323,252.42469067133632,1.5499713389086924,1.246854778511711,0.26082052430644964,0.0,0.0,0.0,1.3038675785064697,1.0472609996795654,0.522201418876648,0.6687119603157043,0.8312791585922241,-0.2797660231590271,34414.23046875,34786.40625,4024.80419921875,7979.23193359375,168,253,168,253,2 -50.0,16,12,201,205,251,255,203.03779020546682,253.9610361299185,1.1347875770149276,1.1678155217776762,-0.3248993708002157,0.0,0.0,0.0,1.2151626348495483,0.9088359475135803,-0.8107903003692627,0.9574903845787048,0.9304108023643494,0.5327690839767456,1851.752197265625,2231.809814453125,255.63705444335938,463.6597900390625,203,254,203,254,2 diff --git a/development/update_tess_sectors.ipynb b/development/update_tess_sectors.ipynb deleted file mode 100644 index 1bf9fe5..0000000 --- a/development/update_tess_sectors.ipynb +++ /dev/null @@ -1,270 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "66eb961d", - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd \n", - "from astropy.time import Time" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "a246d931", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/db/hdghk6ts5g11hr10jq0ss625nf1ny2/T/ipykernel_22283/1019568273.py:1: ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support skipfooter; you can avoid this warning by specifying engine='python'.\n", - " data = pd.read_csv('https://tess.mit.edu/public/files/TESS_orbit_times.csv',skipfooter=1)\n" - ] - } - ], - "source": [ - "data = pd.read_csv('https://tess.mit.edu/public/files/TESS_orbit_times.csv',skipfooter=1)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "01715b14", - "metadata": {}, - "outputs": [], - "source": [ - "sectors = data['Sector'].unique()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "5ec9c6fc", - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 's' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[5], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43ms\u001b[49m[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mStart of Orbit\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;241m.\u001b[39mvalues[\u001b[38;5;241m0\u001b[39m]\n", - "\u001b[0;31mNameError\u001b[0m: name 's' is not defined" - ] - } - ], - "source": [ - "s['Start of Orbit'].values[0]" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "edb6bdbc", - "metadata": {}, - "outputs": [], - "source": [ - "df = pd.DataFrame()\n", - "for sector in sectors:\n", - " s = data.loc[data['Sector'] == sector]\n", - " start = Time(s['Start of Orbit'].values[0])\n", - " end = Time(s['End of Orbit'].values[1])\n", - " entry = pd.DataFrame()\n", - " entry['Sector'] = [sector]\n", - " entry['mjd_start'] = [start.mjd]\n", - " entry['mjd_end'] = [end.mjd]\n", - " df = pd.concat([df,entry])" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "dbd6badf", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Sectormjd_startmjd_end
0158324.81597258352.684028
0258353.60763958381.020833
0358382.22569458408.875000
0458410.40625058436.357639
0558437.48263958463.795139
............
09961045.61458361059.236111
010061073.49305661086.781250
010161100.18055661113.045139
010261126.52083361139.024306
010361151.53125061164.729167
\n", - "

103 rows × 3 columns

\n", - "
" - ], - "text/plain": [ - " Sector mjd_start mjd_end\n", - "0 1 58324.815972 58352.684028\n", - "0 2 58353.607639 58381.020833\n", - "0 3 58382.225694 58408.875000\n", - "0 4 58410.406250 58436.357639\n", - "0 5 58437.482639 58463.795139\n", - ".. ... ... ...\n", - "0 99 61045.614583 61059.236111\n", - "0 100 61073.493056 61086.781250\n", - "0 101 61100.180556 61113.045139\n", - "0 102 61126.520833 61139.024306\n", - "0 103 61151.531250 61164.729167\n", - "\n", - "[103 rows x 3 columns]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "721eb647", - "metadata": {}, - "outputs": [], - "source": [ - "df.to_csv('../tessreduce/sector_mjd.csv',index=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aeea7bcc", - "metadata": {}, - "outputs": [], - "source": [ - "def update_sector_times():\n", - " import pandas as pd \n", - " from astropy.time import Time\n", - " data = pd.read_csv('https://tess.mit.edu/public/files/TESS_orbit_times.csv',skipfooter=1)\n", - " sectors = data['Sector'].unique()\n", - " df = pd.DataFrame()\n", - " for sector in sectors:\n", - " s = data.loc[data['Sector'] == sector]\n", - " start = Time(s['Start of Orbit'].values[0])\n", - " end = Time(s['End of Orbit'].values[1])\n", - " entry = pd.DataFrame()\n", - " entry['Sector'] = [sector]\n", - " entry['mjd_start'] = [start.mjd]\n", - " entry['mjd_end'] = [end.mjd]\n", - " df = pd.concat([df,entry])" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.2" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/SN_Example.ipynb b/examples/SN_Example.ipynb index 1534eab..54502ed 100644 --- a/examples/SN_Example.ipynb +++ b/examples/SN_Example.ipynb @@ -9,18577 +9,142 @@ "import tessreduce as tr\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", - "%matplotlib notebook" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Downloading TPF from TESScut\n", - "made reference\n", - "made source mask\n", - "calculating background\n", - "background subtracted\n", - "aligning images\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n", - "background correlation correction\n", - "field calibration\n", - "target is above -30 dec, calibrating to PS1 photometry.\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "ra = 269.0488792\n", - "dec = 62.75700278\n", - "sector = 21\n", - "size = 90\n", - "\n", - "tess = tr.tessreduce(ra=ra,dec=dec,size=size,sector=sector,diagnostic_plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "20.55841770018856" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.zp" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "(array([[ 5.88699475e+04, 5.88699683e+04, 5.88699892e+04, ...,\n", - " 5.88972186e+04, 5.88972394e+04, 5.88972603e+04],\n", - " [-8.97866702e+00, -1.06631541e+01, -7.55788733e+00, ...,\n", - " 6.54625228e+00, 8.34812046e+00, 8.75370739e+00],\n", - " [ 6.14658814e-01, 6.14888098e-01, 2.04368902e-01, ...,\n", - " 6.18011644e-01, 6.20240229e-01, 6.16788755e-01]]),\n", - " array([[ 5.88699475e+04, 5.88699683e+04, 5.88699892e+04, ...,\n", - " 5.88972186e+04, 5.88972394e+04, 5.88972603e+04],\n", - " [ 3.88753122e-01, 3.27853000e-01, 7.95136643e-02, ...,\n", - " -8.59742571e-02, 1.49371768e-01, -5.08544182e-02],\n", - " [ 4.52363277e-01, 3.77995204e-01, 5.43996482e-01, ...,\n", - " 4.28441703e-01, 2.48777694e-01, 3.54164248e-01]]))" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tess.diff_lc(phot_method='psf',plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "tess.stack_ref()" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.imshow(tess.ref,vmax=50)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.mjd)\n", - "plt.plot(tess.tpf.time.mjd)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.mjd)\n", - "plt.plot(tess.tpf.time.mjd)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you only know the name of the transient, and not ra, dec, or sector, then you can use **sn_lookup**. Here we use it for SN 2020cdj" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "| Sector | Camera | CCD | Covers | Time difference |\n", - "| | | | | (days) |\n", - "|----------+----------+-------+----------+--------------------|\n", - "| 21 | 2 | 1 | False | -980.712 |\n", - "| 48 | 2 | 2 | False | -242.507 |\n", - "| 75 | 1 | 3 | False | 461.285 |\n" - ] - } - ], - "source": [ - "#obs = tr.sn_lookup('2020cdj',time='disc')\n", - "#obs = tr.sn_lookup('sn2020adw')\n", - "obs = tr.spacetime_lookup(ra='10 56 02.77',dec='56 12 15.6',time=59878)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can now put the obs variable into tessreduce, and it will download the sector which overlaps the discovery time. In this case it is sector 21.\n", - "\n", - "**TESSreduce** acts on tpf cuouts from FFIs, these can be input as either a string directing to the saved location of a tpf, a pre-loaded tpf in the workspace, or coordinates to get the tpf from **TESScut**. In this example we will be using **TESScut**.\n", - "\n", - "We get a tpf cutout from the FFIs by utilising **TESScut** through simply giving **tessreduce** the above **obs** variable, or an ra, dec, and sector. To get an accurate assesment of the background around our target, we need a large cutout. Depending on how crowded the field is 30x30 cutouts can work, although it is better to stick to a larger 90x90 cutout and change if needed. The default size is 90x90, however, this can be changed with **tessreduce(size=Num)**.\n", - "\n", - "For high level use, you can get a light curve with 1 line! " - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Downloading TPF from TESScut\n", - "made reference\n", - "made source mask\n", - "calculating background\n", - "background subtracted\n", - "aligning images\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "!!Re-running for difference image!!\n", - "shifting images\n", - "remade mask\n", - "background\n", - "background correlation correction\n", - "field calibration\n", - "target is above -30 dec, calibrating to PS1 photometry.\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess = tr.tessreduce(obs_list=obs[1],diagnostic_plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '%s' message type: \",\n", - " msg_type,\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '%s' message: \", msg_type, msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_%s' callback:\",\n", - " msg_type,\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " buttons: event.buttons,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tess.plotter(ground=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Optimal PSF shift: [-0.79730295 -0.35042763]\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "High correlation between lc and x shift: 0.76\n" - ] - } - ], - "source": [ - "l,s =tess.diff_lc(plot=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib notebook" - ] - }, - { - "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_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(tess.shift[:,1])" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "plt.figure()\n", - "plt.plot(l[1])" - ] - }, - { - "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_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute('tabindex', '0');\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;' +\n", - " 'z-index: 2;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'pointer-events: none;' +\n", - " 'position: relative;' +\n", - " 'z-index: 0;'\n", - " );\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box;' +\n", - " 'left: 0;' +\n", - " 'pointer-events: none;' +\n", - " 'position: absolute;' +\n", - " 'top: 0;' +\n", - " 'z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\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 (width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " /* User Agent sniffing is bad, but WebKit is busted:\n", - " * https://bugs.webkit.org/show_bug.cgi?id=144526\n", - " * https://bugs.webkit.org/show_bug.cgi?id=181818\n", - " * The worst that happens here is that they get an extra browser\n", - " * selection when dragging, if this check fails to catch them.\n", - " */\n", - " var UA = navigator.userAgent;\n", - " var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);\n", - " if(isWebKit) {\n", - " return function (event) {\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We\n", - " * want to control all of the cursor setting manually through\n", - " * the 'cursor' event from matplotlib */\n", - " event.preventDefault()\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " } else {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " canvas_div.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " canvas_div.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " canvas_div.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.canvas_div.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "function getModifiers(event) {\n", - " var mods = [];\n", - " if (event.ctrlKey) {\n", - " mods.push('ctrl');\n", - " }\n", - " if (event.altKey) {\n", - " mods.push('alt');\n", - " }\n", - " if (event.shiftKey) {\n", - " mods.push('shift');\n", - " }\n", - " if (event.metaKey) {\n", - " mods.push('meta');\n", - " }\n", - " return mods;\n", - "}\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " // from https://stackoverflow.com/q/1114465\n", - " var boundingRect = this.canvas.getBoundingClientRect();\n", - " var x = (event.clientX - boundingRect.left) * this.ratio;\n", - " var y = (event.clientY - boundingRect.top) * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " modifiers: getModifiers(event),\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\", \"webp\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you only know the name of the transient, and not ra, dec, or sector, then you can use **sn_lookup**. Here we use it for SN 2020cdj" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "| Sector | Covers | Time difference |\n", + "| | | (days) |\n", + "|----------+----------+--------------------|\n", + "| 14 | False | -177 |\n", + "| 15 | False | -150 |\n", + "| 16 | False | -124 |\n", + "| 17 | False | -98 |\n", + "| 18 | False | -73 |\n", + "| 20 | False | -18 |\n", + "| 21 | True | 0 |\n", + "| 22 | False | 10 |\n", + "| 23 | False | 39 |\n", + "| 24 | False | 68 |\n", + "| 25 | False | 95 |\n", + "| 26 | False | 121 |\n", + "| 40 | False | 502 |\n", + "| 41 | False | 531 |\n", + "| 47 | False | 691 |\n", + "| 48 | False | 720 |\n", + "| 50 | False | 777 |\n", + "| 51 | False | 804 |\n", + "| 52 | False | 830 |\n", + "| 53 | False | 856 |\n", + "| 54 | False | 882 |\n", + "| 55 | False | 909 |\n", + "| 56 | False | 936 |\n", + "| 58 | False | 994 |\n", + "| 59 | False | 1022 |\n", + "| 60 | False | 1049 |\n", + "| 73 | False | 1398 |\n", + "| 74 | False | 1425 |\n", + "| 75 | False | 1452 |\n", + "| 76 | False | 1479 |\n", + "| 77 | False | 1508 |\n", + "| 78 | False | 1536 |\n", + "| 79 | False | 1564 |\n", + "| 81 | False | 1619 |\n", + "| 82 | False | 1645 |\n", + "| 83 | False | 1671 |\n" + ] } ], "source": [ - "plt.figure()\n", - "plt.imshow(np.nanmedian(tess.flux[700:800],axis=0),vmax=5,vmin=-1)" + "obs = tr.sn_lookup('sn2020cdj',time='disc')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Alternatively, if you know the ra, dec, and sector, then you can enter those in instead." + "We can now put the obs variable into tessreduce, and it will download the sector which overlaps the discovery time. In this case it is sector 21.\n", + "\n", + "**TESSreduce** acts on tpf cuouts from FFIs, these can be input as either a string directing to the saved location of a tpf, a pre-loaded tpf in the workspace, or coordinates to get the tpf from **TESScut**. In this example we will be using **TESScut**.\n", + "\n", + "We get a tpf cutout from the FFIs by utilising **TESScut** through simply giving **tessreduce** the above **obs** variable, or an ra, dec, and sector. To get an accurate assesment of the background around our target, we need a large cutout. Depending on how crowded the field is 30x30 cutouts can work, although it is better to stick to a larger 90x90 cutout and change if needed. The default size is 90x90, however, this can be changed with **tessreduce(size=Num)**.\n", + "\n", + "For high level use, you can get a light curve with 1 line! " ] }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, + "execution_count": 4, + "metadata": { + "scrolled": false + }, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "getting TPF from TESScut\n", + "made reference\n", + "made source mask\n", + "calculating background\n", + "background subtracted\n", + "aligning images\n", + "!!Re-running for difference image!!\n", + "shifting images\n", + "remade mask\n", + "background\n", + "background correlation correction\n", + "field calibration\n", + "target is above -30 dec, calibrating to PS1 photometry.\n" + ] + }, { "data": { + "image/png": "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PWWSicVipGkavffee0ntt956K/Xt27eBVpU6xo8fT23atKEdO3YktW/fvp0AJCUMIiL69a9/Tddff319LrFOef/99wkAaZrm/QHwvA4S3+fGJjcRUbt27eimm25Kaps6dSrl5eURUePd8zZt2tA//vGPpLbJkyd7L1Uaq9xNEY4JOwFisRj+9a9/oVWrVjBNE6ZpJsVOAICmaV5sRHl5OQD85JgERITp06fj+uuvh2EYSX29e/fG119/jYKCAq/t008/hd/vPyr2pq5oKFmr46uvvkIgEEBmZubPkKh6UiFnTWOklN6Y+t7ThpKzOlK5n0Bqr10AyMnJQVpaGmbNmoVAIIBBgwYBaBx7WpWa5KyOVO8pczQ+nw89e/bEggULktoXLFiAiy66qIFWVfcQEcaPH4/33nsPn332GTp06JDU36FDB+Tm5iadh3g8jiVLlpzS5+Gyyy7Dxo0bsW7dOu+vV69e+MMf/oB169ahY8eOjVJuAOjTp89RZQi2bNmC9u3bA2i8e15eXv6T9+fGKneTpIGVwFOC//zP/6TFixfTjh07aMWKFXTVVVdReno6fffdd0SkXAO6dOlCixYtoh07dtD06dMpEAjQ1KlTiUhl/zv99NPpkksuoZUrV9K2bdvoySefJCEEffTRR0nHWrhwIQGgzZs3H7WOROrryy67jNauXUsLFy6kNm3a1GmK+pNF1rlz59JLL71EGzdupG3bttHLL79MkUiEbr311lNGzgMHDlDz5s1p+PDhtG7dOvr222/p9ttvJ8MwPNeSVO/pySJnqvezvmQlInruuedozZo19O2339I//vEPCgaD9Mwzz3j9jWFPayNnfewpUzsSKepfffVV2rx5M02cOJHC4bB3TTQGbr75ZsrIyKDFixfXWBLh0UcfpYyMDHrvvfdo48aNNGLEiEaZtruqOyJR45V71apVpOs6PfLII7R161Z66623KBQK0ZtvvumNaYyy33DDDdS6dWsvRf17771HLVq0oDvuuMMb0xjlboqwElYLEvUXDMOgvLw8Gj58OG3atMnrLygooNGjR1NeXh4FAgE666yz6KmnnkqqebVlyxYaPnw4ZWdnUygUonPPPfeoYHkiohEjRtBFF11U41q+//57Gjp0KAWDQWrWrBmNHz+eotFoo5P1448/pu7du1NaWhqFQiHq2rUrPf3002Sa5ikl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", "text/plain": [ - "(array([647]),)" + "
" ] }, - "execution_count": 7, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ - "np.where(np.diff(tess.mjd) > .5)" + "tess = tr.tessreduce(obs_list=obs)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternatively, if you know the ra, dec, and sector, then you can enter those in instead." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Downloading TPF from TESScut\n", + "getting TPF from TESScut\n", "made reference\n", "made source mask\n", "calculating background\n", @@ -18589,19 +154,20 @@ "shifting images\n", "remade mask\n", "background\n", - "Traceback (most recent call last):\n", - " File \"/Users/rri38/miniconda3/lib/python3.12/site-packages/tessreduce/tessreduce.py\", line 2265, in reduce\n", - " self.background(calc_qe = False,strap_iso = False,source_hunt=self._sourcehunt,gauss_smooth=1,interpolate=False)\n", - " File \"/Users/rri38/miniconda3/lib/python3.12/site-packages/tessreduce/tessreduce.py\", line 710, in background\n", - " self._bkg_temporal_smooth()\n", - " File \"/Users/rri38/miniconda3/lib/python3.12/site-packages/tessreduce/tessreduce.py\", line 844, in _bkg_temporal_smooth\n", - " sav = savgol_filter(seg, window_size, 1, axis=0)\t\t\t\t\t # (n_seg, X, Y)\n", - " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", - " File \"/Users/rri38/miniconda3/lib/python3.12/site-packages/scipy/signal/_savitzky_golay.py\", line 345, in savgol_filter\n", - " raise ValueError(\"If mode is 'interp', window_length must be less \"\n", - "ValueError: If mode is 'interp', window_length must be less than or equal to the size of x.\n", - "\n" + "background correlation correction\n", + "field calibration\n", + "target is above -30 dec, calibrating to PS1 photometry.\n" ] + }, + { + "data": { + "image/png": "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PWWSicVipGkavffee0ntt956K/Xt27eBVpU6xo8fT23atKEdO3YktW/fvp0AJCUMIiL69a9/Tddff319LrFOef/99wkAaZrm/QHwvA4S3+fGJjcRUbt27eimm25Kaps6dSrl5eURUePd8zZt2tA//vGPpLbJkyd7L1Uaq9xNEY4JOwFisRj+9a9/oVWrVjBNE6ZpJsVOAICmaV5sRHl5OQD85JgERITp06fj+uuvh2EYSX29e/fG119/jYKCAq/t008/hd/vPyr2pq5oKFmr46uvvkIgEEBmZubPkKh6UiFnTWOklN6Y+t7ThpKzOlK5n0Bqr10AyMnJQVpaGmbNmoVAIIBBgwYBaBx7WpWa5KyOVO8pczQ+nw89e/bEggULktoXLFiAiy66qIFWVfcQEcaPH4/33nsPn332GTp06JDU36FDB+Tm5iadh3g8jiVLlpzS5+Gyyy7Dxo0bsW7dOu+vV69e+MMf/oB169ahY8eOjVJuAOjTp89RZQi2bNmC9u3bA2i8e15eXv6T9+fGKneTpIGVwFOC//zP/6TFixfTjh07aMWKFXTVVVdReno6fffdd0SkXAO6dOlCixYtoh07dtD06dMpEAjQ1KlTiUhl/zv99NPpkksuoZUrV9K2bdvoySefJCEEffTRR0nHWrhwIQGgzZs3H7WOROrryy67jNauXUsLFy6kNm3a1GmK+pNF1rlz59JLL71EGzdupG3bttHLL79MkUiEbr311lNGzgMHDlDz5s1p+PDhtG7dOvr222/p9ttvJ8MwPNeSVO/pySJnqvezvmQlInruuedozZo19O2339I//vEPCgaD9Mwzz3j9jWFPayNnfewpUzsSKepfffVV2rx5M02cOJHC4bB3TTQGbr75ZsrIyKDFixfXWBLh0UcfpYyMDHrvvfdo48aNNGLEiEaZtruqOyJR45V71apVpOs6PfLII7R161Z66623KBQK0ZtvvumNaYyy33DDDdS6dWsvRf17771HLVq0oDvuuMMb0xjlboqwElYLEvUXDMOgvLw8Gj58OG3atMnrLygooNGjR1NeXh4FAgE666yz6KmnnkqqebVlyxYaPnw4ZWdnUygUonPPPfeoYHkiohEjRtBFF11U41q+//57Gjp0KAWDQWrWrBmNHz+eotFoo5P1448/pu7du1NaWhqFQiHq2rUrPf3002Sa5ikl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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ @@ -23968,160 +5534,6 @@ "plt.plot(t.bkg[:,45,45])" ] }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [], - "source": [ - "from tessreduce.helpers import *" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [], - "source": [ - "name = '2020adw'\n", - "url = f'https://www.wis-tns.org/object/{name}' # hard coding in that the event is in the 2000s\n", - "headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'}\n", - "result = requests.get(url, headers=headers)" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'\\n\\n \\n \\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n 2020adw | Transient Name Server\\n\\n \\n \\n \\n\\n \\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n \\n \\n \\n\\n
\\n
\\n
\\n
\\n
\\n \\n
\\n
\\n
\\n \\n
\\n \\n
\\n \\n
\\n
\\n
\\n\\n \\n \"TNS\"\\n \\n
\\n \\n
\\n \\n \\n \\n\\n\\n
\\n \\n
\"IAU\"
\\n
\\n
\\n
\\n
\\n

\\n SN 2020adw\\n

\\n
\\n\\n
\\n
\\n\\n\\n \\n
\\n \\n \\n \\n
\\n
\\n
\\n
\\n\\n
\\n\\n
\\n \\n
\\n
\\n
\\n \\n \\n \\n
\\n\\n \\n \\n\\n \\n
\\n \\n
RA/DEC (2000)
10:53:24.720 +75:56:20.51
163.353 +75.939031
Type
SN Ia
Redshift
0.065
Reporting Group
ZTF
Discovering Data Source
ZTF
Discovery Date
2020-01-16 09:50:07.000
TNS AT
Y
Public
Y
Discovery Mag
19.67
Filter
g-ZTF
Reporter/s
J. Nordin, V. Brinnel, M. Giomi, J. van Santen (HU Berlin), A. Gal-Yam, O. Yaron, S. Schulze (Weizmann) on behalf of ZTF
\\n \\n \\n\\n \\n \\n\\n \\n
\\n \\n\\n

Spectra

 SN_2020adw - 2020-01-31 06:11:41 P60 / SEDM (ZTF)z=
Show H at z=vexp= km/s
Show He at z=vexp= km/s
Show He II at z=vexp= km/s
Show C II at z=vexp= km/s
Show C III at z=vexp= km/s
Show C IV at z=vexp= km/s
Show N II at z=vexp= km/s
Show N III at z=vexp= km/s
Show N IV at z=vexp= km/s
Show N V at z=vexp= km/s
Show O at z=vexp= km/s
Show [O I] at z=vexp= km/s
Show O II at z=vexp= km/s
Show [O II] at z=vexp= km/s
Show [O III] at z=vexp= km/s
Show O V at z=vexp= km/s
Show O VI at z=vexp= km/s
Show Na at z=vexp= km/s
Show Mg at z=vexp= km/s
Show Mg II at z=vexp= km/s
Show Si II at z=vexp= km/s
Show S II at z=vexp= km/s
Show Ca II at z=vexp= km/s
Show [Ca II] at z=vexp= km/s
Show Fe II at z=vexp= km/s
Show Fe III at z=vexp= km/s
Show Å at z=vexp= km/s
Show Å at z=vexp= km/s
Show Å at z=vexp= km/s
Show Å at z=vexp= km/s
Show Tellurics 
Show Galaxy lines at z=
Show WR-WN at z=vexp= km/s
Show WR-WC/O at z=vexp= km/s
   Binning factor: (rounded to nearest integer >1)
Mouse hovers at WL: 0 (rest),0 (observed)

Light curves

 P48_ZTF-Cam_r
 P48_ZTF-Cam_g
 Gaia_Gaia-photometric_G
   
Pointer position (MJD, Mag, Abs.Mag): (0.00, 0.00, 0.00)
Spectra
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
\\n\\n
\\n \\n\\n \\n
\\n
IDObs-date (UT)Tel / InstExp-TimeObserver/sReducer/sGroupSpectrum ascii fileSpectrum fits fileSpec. TypeAssoc. GroupsEnd prop. periodRemarks
\\n\\n
\\n \\n\\n
\\n
60732020-01-31 06:11:41P60 / SEDM2250SEDmRobotautoZTFtns_2020adw_2020-01-31_06-11-41_P60_SEDM_ZTF.asciiObject
   Binning factor: (rounded to nearest integer >1)
Mouse hovers at WL: 0 (rest), 0 (observed)
Show H at z=vexp= km/s
Show He at z=vexp= km/s
Show He II at z=vexp= km/s
Show C II at z=vexp= km/s
Show C III at z=vexp= km/s
Show C IV at z=vexp= km/s
Show N II at z=vexp= km/s
Show N III at z=vexp= km/s
Show N IV at z=vexp= km/s
Show N V at z=vexp= km/s
Show O at z=vexp= km/s
Show [O I] at z=vexp= km/s
Show O II at z=vexp= km/s
Show [O II] at z=vexp= km/s
Show [O III] at z=vexp= km/s
Show O V at z=vexp= km/s
Show O VI at z=vexp= km/s
Show Na at z=vexp= km/s
Show Mg at z=vexp= km/s
Show Mg II at z=vexp= km/s
Show Si II at z=vexp= km/s
Show S II at z=vexp= km/s
Show Ca II at z=vexp= km/s
Show [Ca II] at z=vexp= km/s
Show Fe II at z=vexp= km/s
Show Fe III at z=vexp= km/s
Show Å at z=vexp= km/s
Show Å at z=vexp= km/s
Show Å at z=vexp= km/s
Show Å at z=vexp= km/s
Show Tellurics 
Show Galaxy lines at z=
Show WR-WN at z=vexp= km/s
Show WR-WC/O at z=vexp= km/s
Remarks
\\n
\\n
\\n
Light Curves
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
FilterTel / InstObs-date rangeJD RangePhotometry
r-ZTFP48_ZTF-Cam2020-01-16 05:24:00 - 2020-02-02 06:48:572458864.725 - 2458881.78399315
Photometry
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
IDObs-dateJDMag. / FluxErrLim. Mag./FluxUnitsFilterTel / InstExp-timeObserver/sRemarks
1185842020-02-02 06:48:572458881.783993118.32ABMagr-ZTFP48_ZTF-Cam30ZTF
1142592020-01-18 08:40:352458866.861516218.980.1120.37ABMagr-ZTFP48_ZTF-Cam30
1153242020-01-18 08:40:352458866.861516218.980.1120.37ABMagr-ZTFP48_ZTF-Cam30
1142572020-01-16 05:24:002458864.72520.3177ABMagr-ZTFP48_ZTF-Cam30[Last non detection]
1153222020-01-16 05:24:002458864.72520.3177ABMagr-ZTFP48_ZTF-Cam30[Last non detection]
\\n
g-ZTFP48_ZTF-Cam2020-01-14 10:52:19 - 2020-01-16 09:50:072458862.9529977 - 2458864.90981484
Photometry
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
IDObs-dateJDMag. / FluxErrLim. Mag./FluxUnitsFilterTel / InstExp-timeObserver/sRemarks
1142582020-01-16 09:50:072458864.909814819.670.1820.32ABMagg-ZTFP48_ZTF-Cam30
1153232020-01-16 09:50:072458864.909814819.670.1820.32ABMagg-ZTFP48_ZTF-Cam30
1185832020-01-15 10:24:572458863.933993119.84ABMagg-ZTFP48_ZTF-Cam30ZTF
1185822020-01-14 10:52:192458862.952997719.65ABMagg-ZTFP48_ZTF-Cam30ZTF[Last non detection]
\\n
G-GaiaGaia_Gaia-photometric2019-12-25 11:09:36 - 2020-02-06 17:09:362458842.965 - 2458886.2152
Photometry
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
IDObs-dateJDMag. / FluxErrLim. Mag./FluxUnitsFilterTel / InstExp-timeObserver/sRemarks
1195002020-02-06 17:09:362458886.21518.470.2ABMagG-GaiaGaia_Gaia-photometric60Robot
1194992019-12-25 11:09:362458842.96521.5ABMagG-GaiaGaia_Gaia-photometricRobot[Last non detection]
\\n
\\n
\\n
\\n
AT Reports
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
IDTime received (UT)SenderReporter/sReporting groupDisc. Data SourceRADECDiscovery date (UT)Discovery Mag.FilterRelated filesAT TypeHost nameInternal nameAssoc. GroupsEnd prop. periodRemarksADS BibcodeUnrealAuto classification
614742020-02-10 22:29:12Gaia_Bot1S.T. Hodgkin,E. Breedt,A. Delgado et al.GaiaAlertsGaiaAlerts10:53:24.720+75:56:20.512020-02-06 17:09:36.00018.47G-GaiaPSNGaia20arlGaiaAlertsconfirmed SN Ia in galaxy 2MASX J10532503+7556193N
610312020-02-04 01:13:51ZTF_TESSC. Fremling (Caltech) on behalf of the Zwicky Transient Facility (ZTF) collaboration et al.ZTFZTF10:53:24.576+75:56:20.932020-01-15 10:24:57.00019.84g-ZTFPSNZTF20aakxzutZTFN
595412020-01-23 05:49:02ZTF_AMPEL_COMPLETEJ. Nordin,V. Brinnel,M. Giomi et al.ZTFZTF10:53:24.714+75:56:20.532020-01-16 09:50:07.00019.67g-ZTFPSNZTF19abeizmoZTFSee arXiv:1904.05922 for selection criteria.N
590252020-01-18 09:36:09ZTF_AMPEL_NEWJ. Nordin,V. Brinnel,M. Giomi et al.ZTFZTF10:53:24.716+75:56:20.522020-01-16 09:50:07.00019.67g-ZTFPSNZTF19abeizmoZTFSee arXiv:1904.05922 for selection criteria.2020TNSTR.177....1NN
\\n
\\n
\\n
Classification Reports
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
IDTime received (UT)SenderClassifier/sGroupClassificationRedshiftSpectraRelated filesAssoc. GroupsEnd prop. periodRemarksADS Bibcode
60652020-02-06 01:14:53ZTF_Bot1A. Dahiwale, C. Fremling (Caltech) on behalf of the Zwicky Transient Facility (ZTF)ZTFSN Ia0.0651ZTF2020TNSCR.412....1D
Spectra
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
IDObs-date (UT)Tel / InstExp-TimeObserver/sReducer/sGroupSpectrum ascii fileSpectrum fits fileSpec. TypeAssoc. GroupsEnd prop. periodRemarks
60732020-01-31 06:11:41P60 / SEDM2250SEDmRobotautoZTFtns_2020adw_2020-01-31_06-11-41_P60_SEDM_ZTF.asciiObject
\\n
\\n
\\n
\\n
\\n
\\n \\n

Comments

\\n \\n \\n
\\n \\n\\n
\\n
\\n \\n
TNS
\\n \\n
System
\\n
\\n\\n \\n\\n \\n
\\n\\n
\\n \\n

Object coordinates updated

\\n \\n \\n

Object coordinates updated according to AT-report 61474 of Group GaiaAlerts
Previous RA, DEC: 10:53:24.576, +75:56:20.93 (163.3523981, +75.9391485)
Updated RA, DEC: 10:53:24.720, +75:56:20.51 (163.353, 75.939031)

\\n
\\n \\n
\\n
\\n
\\n \\n\\n
\\n
\\n \\n
TNS
\\n \\n
System
\\n
\\n\\n \\n\\n \\n
\\n\\n
\\n \\n

Object coordinates updated

\\n \\n \\n

Object coordinates updated according to AT-report 61031 of Group ZTF
Previous RA, DEC: 10:53:24.714, +75:56:20.53 (163.35297334, +75.9390356)
Updated RA, DEC: 10:53:24.576, +75:56:20.93 (163.3523981, 75.9391485)

\\n
\\n \\n
\\n
\\n
\\n \\n\\n
\\n
\\n \\n
TNS
\\n \\n
System
\\n
\\n\\n \\n\\n \\n
\\n\\n
\\n \\n

Object coordinates updated

\\n \\n \\n

Object coordinates updated according to AT-report 59541 of Group ZTF
Previous RA, DEC: 10:53:24.716, +75:56:20.52 (163.35298433333, +75.939032566667)
Updated RA, DEC: 10:53:24.714, +75:56:20.53 (163.35297334, 75.9390356)

\\n
\\n \\n
\\n
\\n\\n\\n \\n
\\n
\\n
\\n\\n
\\n\\n\\n\\n
\\n\\n
\\n\\n \\n\\n
\\n \\n
\\n\\n \\n\\n
\\n
\\n
Copyright © 2015
\\n
Built by klido.net
\\n
\\n
\\n
\\n\\n\\n \\n \\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n \\n \\n\\n'" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "result.text" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [], - "source": [ - "ra, dec = result.text.split('
')[-1].split('<')[0].split(' ')\n", - "ra = float(ra); dec = float(dec)\n", - "disc_t = Time(result.text.split('Discovery Date
')[-1].split('<')[0])\n", - "max_t = deepcopy(disc_t)" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [], - "source": [ - "c = SkyCoord(ra,dec, unit=(u.hourangle, u.deg))\n", - "ra = c.ra.deg\n", - "dec = c.dec.deg" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [], - "source": [ - "outID, outEclipLong, outEclipLat, outSecs, outCam, outCcd, outColPix, \\\n", - "outRowPix, scinfo = focal_plane(0, ra, dec)\n", - "\n", - "sec_times = pd.read_csv(package_directory + 'sector_mjd.csv')" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "time = 'disc'\n", - "buffer = 0\n", - "if len(outSecs) > 0:\n", - " ind = outSecs - 1 \n", - "\n", - " new_ind = [i for i in ind if i < len(sec_times)]\n", - "\n", - " secs = sec_times.iloc[new_ind]\n", - " if type(time) == str:\n", - " if (time.lower() == 'disc') | (time.lower() == 'discovery'):\n", - " disc_start = secs['mjd_start'].values - disc_t.mjd\n", - " disc_end = secs['mjd_end'].values - disc_t.mjd\n", - " elif (time.lower() == 'max') | (time.lower() == 'peak'):\n", - " disc_start = secs['mjd_start'].values - max_t.mjd\n", - " disc_end = secs['mjd_end'].values - max_t.mjd\n", - " else:\n", - " disc_start = secs['mjd_start'].values - time\n", - " disc_end = secs['mjd_end'].values - time\n", - "\n", - " covers = []\n", - " differences = []\n", - " tr_list = []\n", - " tab = []\n", - " for i in range(len(disc_start)):\n", - " ds = disc_start[i]\n", - " de = disc_end[i]\n", - " if (ds-buffer <= 0) & (de + buffer >= 0):\n", - " cover = True\n", - " dif = 0\n", - " elif (de+buffer < 0):\n", - " cover = False\n", - " dif = de\n", - " elif (ds-buffer > 0):\n", - " cover = False\n", - " dif = ds\n", - " covers += [cover]\n", - " differences += [dif]\n", - " tab += [[secs.Sector.values[i], cover, dif]]\n", - " tr_list += [[ra, dec, secs.Sector.values[i], cover]]" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "name = 'sn20123'" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'sn'" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "name[:2]" - ] - }, { "cell_type": "code", "execution_count": null, diff --git a/paper_figs/Alignment_example.ipynb b/paper_figs/Alignment_example.ipynb index 8a47150..b40348f 100755 --- a/paper_figs/Alignment_example.ipynb +++ b/paper_figs/Alignment_example.ipynb @@ -3,7 +3,7 @@ { "cell_type": "code", "execution_count": 1, - "id": "72538f29", + "id": "a2ff7bff", "metadata": {}, "outputs": [], "source": [ @@ -24,7 +24,7 @@ { "cell_type": "code", "execution_count": 26, - "id": "d8a8395e", + "id": "790cd653", "metadata": {}, "outputs": [ { @@ -1006,7 +1006,7 @@ { "cell_type": "code", "execution_count": 3, - "id": "9f17c799", + "id": "c2a5374e", "metadata": {}, "outputs": [ { @@ -1027,7 +1027,7 @@ { "cell_type": "code", "execution_count": 50, - "id": "1b610ae5", + "id": "3b697b81", "metadata": {}, "outputs": [ { @@ -2035,7 +2035,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4fac1685", + "id": "9837575b", "metadata": {}, "outputs": [], "source": [] @@ -2043,7 +2043,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -2057,7 +2057,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.2" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/paper_figs/Alignment_example.pdf b/paper_figs/Alignment_example.pdf new file mode 100755 index 0000000..3172061 Binary files /dev/null and b/paper_figs/Alignment_example.pdf differ diff --git a/paper_figs/DN.pdf b/paper_figs/DN.pdf new file mode 100755 index 0000000..9adca3c Binary files /dev/null and b/paper_figs/DN.pdf differ diff --git a/paper_figs/PS1_com_tess_res.pdf b/paper_figs/PS1_com_tess_res.pdf new file mode 100755 index 0000000..bbdc447 Binary files /dev/null and b/paper_figs/PS1_com_tess_res.pdf differ diff --git a/paper_figs/background_example_fqv.pdf b/paper_figs/background_example_fqv.pdf new file mode 100755 index 0000000..1637135 Binary files /dev/null and b/paper_figs/background_example_fqv.pdf differ diff --git a/paper_figs/background_fqv.ipynb b/paper_figs/background_fqv.ipynb index 8817752..a0c3c47 100755 --- a/paper_figs/background_fqv.ipynb +++ b/paper_figs/background_fqv.ipynb @@ -3,7 +3,7 @@ { "cell_type": "code", "execution_count": 1, - "id": "4f608aba", + "id": "8a824aa4", "metadata": {}, "outputs": [], "source": [ @@ -23,8 +23,8 @@ }, { "cell_type": "code", - "execution_count": 4, - "id": "e1fc6c91", + "execution_count": 2, + "id": "ad8d00b6", "metadata": {}, "outputs": [ { @@ -34,16 +34,15 @@ "made reference\n", "made source mask\n", "calculating background\n", - "overshape (90, 90)\n", - "m (90, 90)\n", "background subtracted\n", "aligning images\n", - "!!! skernel 7\n", "!!Re-running for difference image!!\n", "shifting images\n", "remade mask\n", "background\n", - "background correlation correction\n" + "background correlation correction\n", + "field calibration\n", + "target is above -30 dec, calibrating to PS1 photometry.\n" ] }, { @@ -243,15 +242,6 @@ " }\n", "\n", " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\n", " var nentries = entries.length;\n", " for (var i = 0; i < nentries; i++) {\n", " var entry = entries[i];\n", @@ -299,7 +289,7 @@ " // 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 (width != 0 && height != 0) {\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", " fig.request_resize(width, height);\n", " }\n", " }\n", @@ -1043,7 +1033,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -1051,76 +1041,16 @@ }, "metadata": {}, "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "High correlation between lc and x shift: 0.9\n" - ] } ], "source": [ - "tess = tr.tessreduce(tpf='../../../../data/tess/2020fqv.fits',calibrate=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "5a7a4c64", - "metadata": {}, - "outputs": [ - { - "ename": "ConnectionError", - "evalue": "HTTPSConnectionPool(host='archive.stsci.edu', port=443): Max retries exceeded with url: /missions/tess/models/prf_fitsfiles/start_s0004/cam1_ccd3/ (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 65] No route to host'))", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mOSError\u001b[0m Traceback (most recent call last)", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/urllib3/connection.py:203\u001b[0m, in \u001b[0;36mHTTPConnection._new_conn\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 202\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 203\u001b[0m sock \u001b[38;5;241m=\u001b[39m \u001b[43mconnection\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcreate_connection\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 204\u001b[0m \u001b[43m \u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_dns_host\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mport\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 205\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 206\u001b[0m \u001b[43m \u001b[49m\u001b[43msource_address\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msource_address\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 207\u001b[0m \u001b[43m \u001b[49m\u001b[43msocket_options\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msocket_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 208\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 209\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m socket\u001b[38;5;241m.\u001b[39mgaierror \u001b[38;5;28;01mas\u001b[39;00m e:\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/urllib3/util/connection.py:85\u001b[0m, in \u001b[0;36mcreate_connection\u001b[0;34m(address, timeout, source_address, socket_options)\u001b[0m\n\u001b[1;32m 84\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 85\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m err\n\u001b[1;32m 86\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[1;32m 87\u001b[0m \u001b[38;5;66;03m# Break explicitly a reference cycle\u001b[39;00m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/urllib3/util/connection.py:73\u001b[0m, in \u001b[0;36mcreate_connection\u001b[0;34m(address, timeout, source_address, socket_options)\u001b[0m\n\u001b[1;32m 72\u001b[0m sock\u001b[38;5;241m.\u001b[39mbind(source_address)\n\u001b[0;32m---> 73\u001b[0m \u001b[43msock\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43msa\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 74\u001b[0m \u001b[38;5;66;03m# Break explicitly a reference cycle\u001b[39;00m\n", - "\u001b[0;31mOSError\u001b[0m: [Errno 65] No route to host", - "\nThe above exception was the direct cause of the following exception:\n", - "\u001b[0;31mNewConnectionError\u001b[0m Traceback (most recent call last)", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/urllib3/connectionpool.py:790\u001b[0m, in \u001b[0;36mHTTPConnectionPool.urlopen\u001b[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[0m\n\u001b[1;32m 789\u001b[0m \u001b[38;5;66;03m# Make the request on the HTTPConnection object\u001b[39;00m\n\u001b[0;32m--> 790\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_make_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 791\u001b[0m \u001b[43m \u001b[49m\u001b[43mconn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 792\u001b[0m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 793\u001b[0m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 794\u001b[0m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtimeout_obj\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 795\u001b[0m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 796\u001b[0m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 797\u001b[0m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 798\u001b[0m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mretries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 799\u001b[0m \u001b[43m \u001b[49m\u001b[43mresponse_conn\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mresponse_conn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 800\u001b[0m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mpreload_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 801\u001b[0m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdecode_content\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 802\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mresponse_kw\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 803\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 805\u001b[0m \u001b[38;5;66;03m# Everything went great!\u001b[39;00m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/urllib3/connectionpool.py:491\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[0;34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001b[0m\n\u001b[1;32m 490\u001b[0m new_e \u001b[38;5;241m=\u001b[39m _wrap_proxy_error(new_e, conn\u001b[38;5;241m.\u001b[39mproxy\u001b[38;5;241m.\u001b[39mscheme)\n\u001b[0;32m--> 491\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m new_e\n\u001b[1;32m 493\u001b[0m \u001b[38;5;66;03m# conn.request() calls http.client.*.request, not the method in\u001b[39;00m\n\u001b[1;32m 494\u001b[0m \u001b[38;5;66;03m# urllib3.request. It also calls makefile (recv) on the socket.\u001b[39;00m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/urllib3/connectionpool.py:467\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[0;34m(self, conn, method, url, body, headers, retries, timeout, chunked, response_conn, preload_content, decode_content, enforce_content_length)\u001b[0m\n\u001b[1;32m 466\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 467\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_validate_conn\u001b[49m\u001b[43m(\u001b[49m\u001b[43mconn\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 468\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (SocketTimeout, BaseSSLError) \u001b[38;5;28;01mas\u001b[39;00m e:\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/urllib3/connectionpool.py:1096\u001b[0m, in \u001b[0;36mHTTPSConnectionPool._validate_conn\u001b[0;34m(self, conn)\u001b[0m\n\u001b[1;32m 1095\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m conn\u001b[38;5;241m.\u001b[39mis_closed:\n\u001b[0;32m-> 1096\u001b[0m \u001b[43mconn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1098\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m conn\u001b[38;5;241m.\u001b[39mis_verified:\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/urllib3/connection.py:611\u001b[0m, in \u001b[0;36mHTTPSConnection.connect\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 610\u001b[0m sock: socket\u001b[38;5;241m.\u001b[39msocket \u001b[38;5;241m|\u001b[39m ssl\u001b[38;5;241m.\u001b[39mSSLSocket\n\u001b[0;32m--> 611\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msock \u001b[38;5;241m=\u001b[39m sock \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_new_conn\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 612\u001b[0m server_hostname: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhost\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/urllib3/connection.py:218\u001b[0m, in \u001b[0;36mHTTPConnection._new_conn\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 217\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m--> 218\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m NewConnectionError(\n\u001b[1;32m 219\u001b[0m \u001b[38;5;28mself\u001b[39m, \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mFailed to establish a new connection: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00me\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 220\u001b[0m ) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n\u001b[1;32m 222\u001b[0m \u001b[38;5;66;03m# Audit hooks are only available in Python 3.8+\u001b[39;00m\n", - "\u001b[0;31mNewConnectionError\u001b[0m: : Failed to establish a new connection: [Errno 65] No route to host", - "\nThe above exception was the direct cause of the following exception:\n", - "\u001b[0;31mMaxRetryError\u001b[0m Traceback (most recent call last)", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/requests/adapters.py:667\u001b[0m, in \u001b[0;36mHTTPAdapter.send\u001b[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001b[0m\n\u001b[1;32m 666\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 667\u001b[0m resp \u001b[38;5;241m=\u001b[39m \u001b[43mconn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 668\u001b[0m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 669\u001b[0m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 670\u001b[0m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 671\u001b[0m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 672\u001b[0m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 673\u001b[0m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 674\u001b[0m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 675\u001b[0m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 676\u001b[0m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmax_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 677\u001b[0m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 678\u001b[0m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 679\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 681\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (ProtocolError, \u001b[38;5;167;01mOSError\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m err:\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/urllib3/connectionpool.py:844\u001b[0m, in \u001b[0;36mHTTPConnectionPool.urlopen\u001b[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, preload_content, decode_content, **response_kw)\u001b[0m\n\u001b[1;32m 842\u001b[0m new_e \u001b[38;5;241m=\u001b[39m ProtocolError(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mConnection aborted.\u001b[39m\u001b[38;5;124m\"\u001b[39m, new_e)\n\u001b[0;32m--> 844\u001b[0m retries \u001b[38;5;241m=\u001b[39m \u001b[43mretries\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mincrement\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 845\u001b[0m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43merror\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnew_e\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m_pool\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m_stacktrace\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msys\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexc_info\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m]\u001b[49m\n\u001b[1;32m 846\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 847\u001b[0m retries\u001b[38;5;241m.\u001b[39msleep()\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/urllib3/util/retry.py:515\u001b[0m, in \u001b[0;36mRetry.increment\u001b[0;34m(self, method, url, response, error, _pool, _stacktrace)\u001b[0m\n\u001b[1;32m 514\u001b[0m reason \u001b[38;5;241m=\u001b[39m error \u001b[38;5;129;01mor\u001b[39;00m ResponseError(cause)\n\u001b[0;32m--> 515\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m MaxRetryError(_pool, url, reason) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mreason\u001b[39;00m \u001b[38;5;66;03m# type: ignore[arg-type]\u001b[39;00m\n\u001b[1;32m 517\u001b[0m log\u001b[38;5;241m.\u001b[39mdebug(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mIncremented Retry for (url=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m): \u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[38;5;124m\"\u001b[39m, url, new_retry)\n", - "\u001b[0;31mMaxRetryError\u001b[0m: HTTPSConnectionPool(host='archive.stsci.edu', port=443): Max retries exceeded with url: /missions/tess/models/prf_fitsfiles/start_s0004/cam1_ccd3/ (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 65] No route to host'))", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[0;31mConnectionError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[12], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mtess\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdiff_lc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mphot_method\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mpsf\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43mplot\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m;\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/tessreduce/tessreduce.py:1223\u001b[0m, in \u001b[0;36mtessreduce.diff_lc\u001b[0;34m(self, time, x, y, ra, dec, tar_ap, sky_in, sky_out, phot_method, psf_snap, bkg_poly_order, plot, savename, mask, diff)\u001b[0m\n\u001b[1;32m 1220\u001b[0m \t\u001b[38;5;28;01mif\u001b[39;00m psf_snap \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 1221\u001b[0m \t\tpsf_snap \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbrightest\u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[0;32m-> 1223\u001b[0m \ttar, tar_err \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpsf_photometry\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m,\u001b[49m\u001b[43my\u001b[49m\u001b[43m,\u001b[49m\u001b[43mdiff\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdiff\u001b[49m\u001b[43m,\u001b[49m\u001b[43msnap\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mpsf_snap\u001b[49m\u001b[43m,\u001b[49m\u001b[43mbkg_poly_order\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbkg_poly_order\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1224\u001b[0m nan_ind \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mwhere(np\u001b[38;5;241m.\u001b[39mnansum(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mflux,axis\u001b[38;5;241m=\u001b[39m(\u001b[38;5;241m1\u001b[39m,\u001b[38;5;241m2\u001b[39m))\u001b[38;5;241m==\u001b[39m\u001b[38;5;241m0\u001b[39m,\u001b[38;5;28;01mTrue\u001b[39;00m,\u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[1;32m 1225\u001b[0m nan_ind[\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mref_ind] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/tessreduce/tessreduce.py:1727\u001b[0m, in \u001b[0;36mtessreduce.psf_photometry\u001b[0;34m(self, xPix, yPix, size, snap, ext_shift, plot, diff, bkg_poly_order)\u001b[0m\n\u001b[1;32m 1707\u001b[0m \t\u001b[38;5;66;03m#prf, cutouts = self._psf_initialise(size,(xPix,yPix)) # gather base PRF and the array of cutouts data\u001b[39;00m\n\u001b[1;32m 1708\u001b[0m \t\u001b[38;5;66;03m#xShifts = []\u001b[39;00m\n\u001b[1;32m 1709\u001b[0m \t\u001b[38;5;66;03m#yShifts = []\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1724\u001b[0m \t\u001b[38;5;66;03m#\tax[2].set_ylabel('yShift')\u001b[39;00m\n\u001b[1;32m 1725\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 1726\u001b[0m \t\u001b[38;5;28;01mif\u001b[39;00m snap \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbrightest\u001b[39m\u001b[38;5;124m'\u001b[39m: \u001b[38;5;66;03m# each cutout has position snapped to brightest frame fit position\u001b[39;00m\n\u001b[0;32m-> 1727\u001b[0m \t\tprf, cutouts \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_psf_initialise\u001b[49m\u001b[43m(\u001b[49m\u001b[43msize\u001b[49m\u001b[43m,\u001b[49m\u001b[43m(\u001b[49m\u001b[43mxPix\u001b[49m\u001b[43m,\u001b[49m\u001b[43myPix\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43mref\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mdiff\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# gather base PRF and the array of cutouts data\u001b[39;00m\n\u001b[1;32m 1728\u001b[0m \t\tbkg \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mbkg[:,\u001b[38;5;28mint\u001b[39m(yPix),\u001b[38;5;28mint\u001b[39m(xPix)]\n\u001b[1;32m 1729\u001b[0m \t\t\u001b[38;5;66;03m#lowbkg = bkg < np.nanpercentile(bkg,16)\u001b[39;00m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/tessreduce/tessreduce.py:1588\u001b[0m, in \u001b[0;36mtessreduce._psf_initialise\u001b[0;34m(self, cutoutSize, loc, time_ind, ref)\u001b[0m\n\u001b[1;32m 1585\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(loc[\u001b[38;5;241m1\u001b[39m], (\u001b[38;5;28mfloat\u001b[39m, np\u001b[38;5;241m.\u001b[39mfloating, np\u001b[38;5;241m.\u001b[39mfloat32, np\u001b[38;5;241m.\u001b[39mfloat64)):\n\u001b[1;32m 1586\u001b[0m \tloc[\u001b[38;5;241m1\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(loc[\u001b[38;5;241m1\u001b[39m] \u001b[38;5;241m+\u001b[39m \u001b[38;5;241m0.5\u001b[39m)\n\u001b[0;32m-> 1588\u001b[0m prf \u001b[38;5;241m=\u001b[39m \u001b[43mTESS_PRF\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtpf\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcamera\u001b[49m\u001b[43m,\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtpf\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mccd\u001b[49m\u001b[43m,\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtpf\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msector\u001b[49m\u001b[43m,\u001b[49m\u001b[43mcol\u001b[49m\u001b[43m,\u001b[49m\u001b[43mrow\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# initialise psf kernel\u001b[39;00m\n\u001b[1;32m 1589\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m ref:\n\u001b[1;32m 1590\u001b[0m \tcutout \u001b[38;5;241m=\u001b[39m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mflux\u001b[38;5;241m+\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mref)[time_ind,loc[\u001b[38;5;241m1\u001b[39m]\u001b[38;5;241m-\u001b[39mcutoutSize\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m2\u001b[39m:loc[\u001b[38;5;241m1\u001b[39m]\u001b[38;5;241m+\u001b[39m\u001b[38;5;241m1\u001b[39m\u001b[38;5;241m+\u001b[39mcutoutSize\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m2\u001b[39m,loc[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m-\u001b[39mcutoutSize\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m2\u001b[39m:loc[\u001b[38;5;241m0\u001b[39m]\u001b[38;5;241m+\u001b[39m\u001b[38;5;241m1\u001b[39m\u001b[38;5;241m+\u001b[39mcutoutSize\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m/\u001b[39m\u001b[38;5;241m2\u001b[39m] \u001b[38;5;66;03m# gather cutouts\u001b[39;00m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/PRF/prf.py:68\u001b[0m, in \u001b[0;36mTESS_PRF.__init__\u001b[0;34m(self, cam, ccd, sector, colnum, rownum, localdatadir)\u001b[0m\n\u001b[1;32m 65\u001b[0m soup \u001b[38;5;241m=\u001b[39m BeautifulSoup(page, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhtml.parser\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 66\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m [url \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m/\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m+\u001b[39m node\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhref\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;28;01mfor\u001b[39;00m node \u001b[38;5;129;01min\u001b[39;00m soup\u001b[38;5;241m.\u001b[39mfind_all(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ma\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;28;01mif\u001b[39;00m node\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhref\u001b[39m\u001b[38;5;124m'\u001b[39m)\u001b[38;5;241m.\u001b[39mendswith(ext)]\n\u001b[0;32m---> 68\u001b[0m filelist \u001b[38;5;241m=\u001b[39m [file \u001b[38;5;28;01mfor\u001b[39;00m file \u001b[38;5;129;01min\u001b[39;00m \u001b[43mlistFD\u001b[49m\u001b[43m(\u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mext\u001b[49m\u001b[43m)\u001b[49m]\n\u001b[1;32m 69\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 70\u001b[0m filelist \u001b[38;5;241m=\u001b[39m glob(os\u001b[38;5;241m.\u001b[39mpath\u001b[38;5;241m.\u001b[39mjoin(localdatadir, subdir) \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m*.fits\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/PRF/prf.py:64\u001b[0m, in \u001b[0;36mTESS_PRF.__init__..listFD\u001b[0;34m(url, ext)\u001b[0m\n\u001b[1;32m 63\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mlistFD\u001b[39m(url, ext\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m'\u001b[39m):\n\u001b[0;32m---> 64\u001b[0m page \u001b[38;5;241m=\u001b[39m \u001b[43mrequests\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mverify\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mtext\n\u001b[1;32m 65\u001b[0m soup \u001b[38;5;241m=\u001b[39m BeautifulSoup(page, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhtml.parser\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 66\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m [url \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m/\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m+\u001b[39m node\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhref\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;28;01mfor\u001b[39;00m node \u001b[38;5;129;01min\u001b[39;00m soup\u001b[38;5;241m.\u001b[39mfind_all(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124ma\u001b[39m\u001b[38;5;124m'\u001b[39m) \u001b[38;5;28;01mif\u001b[39;00m node\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhref\u001b[39m\u001b[38;5;124m'\u001b[39m)\u001b[38;5;241m.\u001b[39mendswith(ext)]\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/requests/api.py:73\u001b[0m, in \u001b[0;36mget\u001b[0;34m(url, params, **kwargs)\u001b[0m\n\u001b[1;32m 62\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mget\u001b[39m(url, params\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 63\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124mr\u001b[39m\u001b[38;5;124;03m\"\"\"Sends a GET request.\u001b[39;00m\n\u001b[1;32m 64\u001b[0m \n\u001b[1;32m 65\u001b[0m \u001b[38;5;124;03m :param url: URL for the new :class:`Request` object.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[38;5;124;03m :rtype: requests.Response\u001b[39;00m\n\u001b[1;32m 71\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m---> 73\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mget\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mparams\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mparams\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/requests/api.py:59\u001b[0m, in \u001b[0;36mrequest\u001b[0;34m(method, url, **kwargs)\u001b[0m\n\u001b[1;32m 55\u001b[0m \u001b[38;5;66;03m# By using the 'with' statement we are sure the session is closed, thus we\u001b[39;00m\n\u001b[1;32m 56\u001b[0m \u001b[38;5;66;03m# avoid leaving sockets open which can trigger a ResourceWarning in some\u001b[39;00m\n\u001b[1;32m 57\u001b[0m \u001b[38;5;66;03m# cases, and look like a memory leak in others.\u001b[39;00m\n\u001b[1;32m 58\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m sessions\u001b[38;5;241m.\u001b[39mSession() \u001b[38;5;28;01mas\u001b[39;00m session:\n\u001b[0;32m---> 59\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43msession\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmethod\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/requests/sessions.py:589\u001b[0m, in \u001b[0;36mSession.request\u001b[0;34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[0m\n\u001b[1;32m 584\u001b[0m send_kwargs \u001b[38;5;241m=\u001b[39m {\n\u001b[1;32m 585\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtimeout\u001b[39m\u001b[38;5;124m\"\u001b[39m: timeout,\n\u001b[1;32m 586\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mallow_redirects\u001b[39m\u001b[38;5;124m\"\u001b[39m: allow_redirects,\n\u001b[1;32m 587\u001b[0m }\n\u001b[1;32m 588\u001b[0m send_kwargs\u001b[38;5;241m.\u001b[39mupdate(settings)\n\u001b[0;32m--> 589\u001b[0m resp \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprep\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43msend_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 591\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m resp\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/requests/sessions.py:703\u001b[0m, in \u001b[0;36mSession.send\u001b[0;34m(self, request, **kwargs)\u001b[0m\n\u001b[1;32m 700\u001b[0m start \u001b[38;5;241m=\u001b[39m preferred_clock()\n\u001b[1;32m 702\u001b[0m \u001b[38;5;66;03m# Send the request\u001b[39;00m\n\u001b[0;32m--> 703\u001b[0m r \u001b[38;5;241m=\u001b[39m \u001b[43madapter\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 705\u001b[0m \u001b[38;5;66;03m# Total elapsed time of the request (approximately)\u001b[39;00m\n\u001b[1;32m 706\u001b[0m elapsed \u001b[38;5;241m=\u001b[39m preferred_clock() \u001b[38;5;241m-\u001b[39m start\n", - "File \u001b[0;32m~/miniconda3/lib/python3.12/site-packages/requests/adapters.py:700\u001b[0m, in \u001b[0;36mHTTPAdapter.send\u001b[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001b[0m\n\u001b[1;32m 696\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(e\u001b[38;5;241m.\u001b[39mreason, _SSLError):\n\u001b[1;32m 697\u001b[0m \u001b[38;5;66;03m# This branch is for urllib3 v1.22 and later.\u001b[39;00m\n\u001b[1;32m 698\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m SSLError(e, request\u001b[38;5;241m=\u001b[39mrequest)\n\u001b[0;32m--> 700\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mConnectionError\u001b[39;00m(e, request\u001b[38;5;241m=\u001b[39mrequest)\n\u001b[1;32m 702\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m ClosedPoolError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 703\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mConnectionError\u001b[39;00m(e, request\u001b[38;5;241m=\u001b[39mrequest)\n", - "\u001b[0;31mConnectionError\u001b[0m: HTTPSConnectionPool(host='archive.stsci.edu', port=443): Max retries exceeded with url: /missions/tess/models/prf_fitsfiles/start_s0004/cam1_ccd3/ (Caused by NewConnectionError(': Failed to establish a new connection: [Errno 65] No route to host'))" - ] - } - ], - "source": [ - "tess.diff_lc(phot_method='psf',plot=True);" + "tess = tr.tessreduce(tpf='../../../../data/tess/2020fqv.fits',reduce=True)" ] }, { "cell_type": "code", - "execution_count": 14, - "id": "0d1d9eb7", + "execution_count": 8, + "id": "78b3942e", "metadata": {}, "outputs": [ { @@ -2111,7 +2041,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -2122,22 +2052,13 @@ } ], "source": [ - "plt.figure()\n", - "plt.imshow(tess.mask,origin='lower')\n", - "plt.tick_params(\n", - " axis='both', # changes apply to the x-axis\n", - " which='both', # both major and minor ticks are affected\n", - " bottom=False, # ticks along the bottom edge are off\n", - " left=False, \n", - " labelbottom=False,\n", - " labelleft=False) # labels along the bottom edge are off\n", - "plt.savefig('fqv_mask.pdf', bbox_inches = \"tight\")" + "tess.diff_lc(phot_method='psf',plot=True);" ] }, { "cell_type": "code", - "execution_count": 9, - "id": "bf09dd83", + "execution_count": 14, + "id": "f6e11e1b", "metadata": {}, "outputs": [ { @@ -3128,7 +3049,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -3136,48 +3057,25 @@ }, "metadata": {}, "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "import numpy as np\n", - "fig_width_pt = 240.0 # Get this from LaTeX using \\showthe\\columnwidth\n", - "inches_per_pt = 1.0/72.27\t\t\t # Convert pt to inches\n", - "golden_mean = (np.sqrt(5)-1.0)/2.0\t\t # Aesthetic ratio\n", - "fig_width = fig_width_pt*inches_per_pt # width in inches\n", - "plt.figure(figsize=(1.5*fig_width,1*fig_width))\n", - "plt.plot(tess.lc[0],tess.shift[:,0],'.',label='Row shift')\n", - "plt.plot(tess.lc[0],tess.shift[:,1],'.',label='Col shift')\n", - "plt.ylabel('Shift (pixels)',fontsize=15)\n", - "plt.xlabel('Time (MJD)',fontsize=15)\n", - "plt.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "0f6489e7", - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.patheffects as PathEffects\n", - "\n", - "from astropy.visualization import simple_norm" + "plt.figure()\n", + "plt.imshow(tess.mask,origin='lower')\n", + "plt.tick_params(\n", + " axis='both', # changes apply to the x-axis\n", + " which='both', # both major and minor ticks are affected\n", + " bottom=False, # ticks along the bottom edge are off\n", + " left=False, \n", + " labelbottom=False,\n", + " labelleft=False) # labels along the bottom edge are off\n", + "plt.savefig('fqv_mask.pdf', bbox_inches = \"tight\")" ] }, { "cell_type": "code", - "execution_count": 39, - "id": "e4f808a4", + "execution_count": 9, + "id": "d7d1692b", "metadata": {}, "outputs": [ { @@ -3377,15 +3275,6 @@ " }\n", "\n", " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\n", " var nentries = entries.length;\n", " for (var i = 0; i < nentries; i++) {\n", " var entry = entries[i];\n", @@ -3433,7 +3322,7 @@ " // 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 (width != 0 && height != 0) {\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", " fig.request_resize(width, height);\n", " }\n", " }\n", @@ -4177,7 +4066,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -4185,82 +4074,46 @@ }, "metadata": {}, "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "i = 45\n", - "\n", - "plt.figure(figsize=(3*fig_width,1*fig_width))\n", - "plt.subplot(141)\n", - "f = tess.tpf.flux.value[i]\n", - "norm = simple_norm(f,'sqrt',min_cut=np.nanpercentile(f,0),max_cut=np.nanpercentile(f,90))\n", - "plt.imshow(f,origin='lower',norm=norm)\n", - "#plt.ylabel('Row',fontsize=15)\n", - "#plt.xlabel('Column',fontsize=15)\n", - "plt.title('Raw image',fontsize=13)\n", - "plt.tick_params(\n", - " axis='both', # changes apply to the x-axis\n", - " which='both', # both major and minor ticks are affected\n", - " bottom=False, # ticks along the bottom edge are off\n", - " left=False, \n", - " labelbottom=False,\n", - " labelleft=False) # labels along the bottom edge are off\n", - "#plt.annotate(\"a)\", (10, 75),\n", - "# size=20, ha=\"center\",color='w', path_effects=[PathEffects.withStroke(linewidth=.5,\n", - "# foreground=\"k\")])\n", - "plt.subplot(142)\n", - "#plt.imshow(tess.bkg[700]/tess.qe[700],origin='lower',vmin=8000,vmax=9000)\n", - "f = tess.bkg[i]\n", - "norm = simple_norm(f,'sqrt',min_cut=np.nanpercentile(f,0),max_cut=np.nanpercentile(f,90))\n", - "plt.imshow(f,origin='lower',norm=norm)\n", - "#plt.imshow(tess.bkg[i],origin='lower',vmin=8000,vmax=9000)\n", - "#plt.xlabel('Column',fontsize=15)\n", - "plt.title('Smooth background',fontsize=13)\n", - "plt.tick_params(\n", - " axis='both', # changes apply to the x-axis\n", - " which='both', # both major and minor ticks are affected\n", - " bottom=False, # ticks along the bottom edge are off\n", - " left=False, \n", - " labelbottom=False,\n", - " labelleft=False) # labels along the bottom edge are off\n", - "\n", - "plt.subplot(143)\n", - "f = tess.bkg[i]*tess.qe[i]\n", - "norm = simple_norm(f,'sqrt',min_cut=np.nanpercentile(f,0),max_cut=np.nanpercentile(f,90))\n", - "plt.imshow(f,origin='lower',norm=norm)\n", - "\n", - "plt.imshow(f,origin='lower',norm=norm)\n", - "#plt.xlabel('Column',fontsize=15)\n", - "plt.title('Complete background',fontsize=13)\n", - "plt.tick_params(\n", - " axis='both', # changes apply to the x-axis\n", - " which='both', # both major and minor ticks are affected\n", - " bottom=False, # ticks along the bottom edge are off\n", - " left=False, \n", - " labelbottom=False,\n", - " labelleft=False) # labels along the bottom edge are off\n", - "\n", - "plt.subplot(144)\n", - "f = tess.flux[i]+tess.ref\n", - "norm = simple_norm(f,'sqrt',min_cut=np.nanpercentile(f,1),max_cut=np.nanpercentile(f,95))\n", - "plt.imshow(f,origin='lower',norm=norm)\n", - "\n", - "#plt.xlabel('Column',fontsize=15)\n", - "plt.title('Background subtracted',fontsize=13)\n", - "plt.tick_params(\n", - " axis='both', # changes apply to the x-axis\n", - " which='both', # both major and minor ticks are affected\n", - " bottom=False, # ticks along the bottom edge are off\n", - " left=False, \n", - " labelbottom=False,\n", - " labelleft=False) # labels along the bottom edge are off\n", - "#plt.savefig('background_example_fqv.pdf', bbox_inches = \"tight\")" + "import numpy as np\n", + "fig_width_pt = 240.0 # Get this from LaTeX using \\showthe\\columnwidth\n", + "inches_per_pt = 1.0/72.27\t\t\t # Convert pt to inches\n", + "golden_mean = (np.sqrt(5)-1.0)/2.0\t\t # Aesthetic ratio\n", + "fig_width = fig_width_pt*inches_per_pt # width in inches\n", + "plt.figure(figsize=(1.5*fig_width,1*fig_width))\n", + "plt.plot(tess.lc[0],tess.shift[:,0],'.',label='Row shift')\n", + "plt.plot(tess.lc[0],tess.shift[:,1],'.',label='Col shift')\n", + "plt.ylabel('Shift (pixels)',fontsize=15)\n", + "plt.xlabel('Time (MJD)',fontsize=15)\n", + "plt.legend()" ] }, { "cell_type": "code", - "execution_count": 49, - "id": "4a768a5f", + "execution_count": 3, + "id": "e9534d9f", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.patheffects as PathEffects" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "5da126d3", "metadata": {}, "outputs": [ { @@ -4460,15 +4313,6 @@ " }\n", "\n", " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " // There's no need to resize if the WebSocket is not connected:\n", - " // - If it is still connecting, then we will get an initial resize from\n", - " // Python once it connects.\n", - " // - If it has disconnected, then resizing will clear the canvas and\n", - " // never get anything back to refill it, so better to not resize and\n", - " // keep something visible.\n", - " if (fig.ws.readyState != 1) {\n", - " return;\n", - " }\n", " var nentries = entries.length;\n", " for (var i = 0; i < nentries; i++) {\n", " var entry = entries[i];\n", @@ -4516,7 +4360,7 @@ " // 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 (width != 0 && height != 0) {\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", " fig.request_resize(width, height);\n", " }\n", " }\n", @@ -5260,7 +5104,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -5271,13 +5115,9 @@ } ], "source": [ - "i = 45\n", - "\n", "plt.figure(figsize=(3*fig_width,1*fig_width))\n", "plt.subplot(141)\n", - "f = tess.tpf.flux.value[i]\n", - "norm = simple_norm(f,'sqrt',min_cut=np.nanpercentile(f,0),max_cut=np.nanpercentile(f,90))\n", - "plt.imshow(f,origin='lower',norm=norm)\n", + "plt.imshow(tess.tpf.flux.value[700],origin='lower',vmin=8000,vmax=9000)\n", "#plt.ylabel('Row',fontsize=15)\n", "#plt.xlabel('Column',fontsize=15)\n", "plt.title('Raw image',fontsize=13)\n", @@ -5293,10 +5133,7 @@ "# foreground=\"k\")])\n", "plt.subplot(142)\n", "#plt.imshow(tess.bkg[700]/tess.qe[700],origin='lower',vmin=8000,vmax=9000)\n", - "f = tess.bkg[i]\n", - "norm = simple_norm(f,'sqrt',min_cut=np.nanpercentile(f,0),max_cut=np.nanpercentile(f,90))\n", - "plt.imshow(f,origin='lower',norm=norm)\n", - "#plt.imshow(tess.bkg[i],origin='lower',vmin=8000,vmax=9000)\n", + "plt.imshow(tess.bkg[700],origin='lower',vmin=8000,vmax=9000)\n", "#plt.xlabel('Column',fontsize=15)\n", "plt.title('Smooth background',fontsize=13)\n", "plt.tick_params(\n", @@ -5308,15 +5145,9 @@ " labelleft=False) # labels along the bottom edge are off\n", "\n", "plt.subplot(143)\n", - "q = tr.deepcopy(tess.qe[i])\n", - "#q[q==1] = 0\n", - "f = tess.bkg[i]*q - tess.bkg[i]\n", - "norm = simple_norm(f,'sqrt',min_cut=np.nanpercentile(f[f>0],0),max_cut=np.nanpercentile(f[f>0],90))\n", - "plt.imshow(f,origin='lower',norm=norm)\n", - "\n", - "plt.imshow(f,origin='lower',norm=norm)\n", + "plt.imshow(tess.bkg[700]*tess.qe[700],origin='lower',vmin=8000,vmax=9000)\n", "#plt.xlabel('Column',fontsize=15)\n", - "plt.title('Strap background',fontsize=13)\n", + "plt.title('Complete background',fontsize=13)\n", "plt.tick_params(\n", " axis='both', # changes apply to the x-axis\n", " which='both', # both major and minor ticks are affected\n", @@ -5326,10 +5157,7 @@ " labelleft=False) # labels along the bottom edge are off\n", "\n", "plt.subplot(144)\n", - "f = tess.flux[i]+tess.ref\n", - "norm = simple_norm(f,'sqrt',min_cut=np.nanpercentile(f,1),max_cut=np.nanpercentile(f,95))\n", - "plt.imshow(f,origin='lower',norm=norm)\n", - "\n", + "plt.imshow(tess.flux[700]+tess.ref,origin='lower',vmin=0,vmax=50)\n", "#plt.xlabel('Column',fontsize=15)\n", "plt.title('Background subtracted',fontsize=13)\n", "plt.tick_params(\n", @@ -5339,13 +5167,13 @@ " left=False, \n", " labelbottom=False,\n", " labelleft=False) # labels along the bottom edge are off\n", - "plt.savefig('background_example_fqv_2.pdf', bbox_inches = \"tight\",dpi=300)" + "plt.savefig('background_example_fqv.pdf', bbox_inches = \"tight\")" ] }, { "cell_type": "code", "execution_count": null, - "id": "427c8580", + "id": "7c3e951f", "metadata": {}, "outputs": [], "source": [] diff --git a/paper_figs/correlation_correction_example.pdf b/paper_figs/correlation_correction_example.pdf new file mode 100644 index 0000000..2627711 Binary files /dev/null and b/paper_figs/correlation_correction_example.pdf differ diff --git a/paper_figs/fqv_mask.pdf b/paper_figs/fqv_mask.pdf new file mode 100644 index 0000000..6fb68a8 Binary files /dev/null and b/paper_figs/fqv_mask.pdf differ diff --git a/paper_figs/full_reduction_example_2020cdj.pdf b/paper_figs/full_reduction_example_2020cdj.pdf new file mode 100755 index 0000000..6375c1c Binary files /dev/null and b/paper_figs/full_reduction_example_2020cdj.pdf differ diff --git a/paper_figs/full_reduction_example_2020cdj.png b/paper_figs/full_reduction_example_2020cdj.png new file mode 100644 index 0000000..c207254 Binary files /dev/null and b/paper_figs/full_reduction_example_2020cdj.png differ diff --git a/paper_figs/grb191016a.pdf b/paper_figs/grb191016a.pdf new file mode 100755 index 0000000..9cdab75 Binary files /dev/null and b/paper_figs/grb191016a.pdf differ diff --git a/paper_figs/sn2018emt.pdf b/paper_figs/sn2018emt.pdf new file mode 100755 index 0000000..f84cb2d Binary files /dev/null and b/paper_figs/sn2018emt.pdf differ diff --git a/paper_figs/sn2018fub_SLR.pdf b/paper_figs/sn2018fub_SLR.pdf new file mode 100755 index 0000000..1007dd9 Binary files /dev/null and b/paper_figs/sn2018fub_SLR.pdf differ diff --git a/paper_figs/sn2018fub_diff_diag.pdf b/paper_figs/sn2018fub_diff_diag.pdf new file mode 100755 index 0000000..32aa4ab Binary files /dev/null and b/paper_figs/sn2018fub_diff_diag.pdf differ diff --git a/paper_figs/sn2018fub_disp.pdf b/paper_figs/sn2018fub_disp.pdf new file mode 100755 index 0000000..5528ff2 Binary files /dev/null and b/paper_figs/sn2018fub_disp.pdf differ diff --git a/paper_figs/sn2018fub_disp_corr.pdf b/paper_figs/sn2018fub_disp_corr.pdf new file mode 100755 index 0000000..17b44da Binary files /dev/null and b/paper_figs/sn2018fub_disp_corr.pdf differ diff --git a/paper_figs/sn2018fubcal_sources.pdf b/paper_figs/sn2018fubcal_sources.pdf new file mode 100755 index 0000000..5938b33 Binary files /dev/null and b/paper_figs/sn2018fubcal_sources.pdf differ diff --git a/paper_figs/sn2018fubcal_zp.pdf b/paper_figs/sn2018fubcal_zp.pdf new file mode 100755 index 0000000..9e7c10d Binary files /dev/null and b/paper_figs/sn2018fubcal_zp.pdf differ diff --git a/paper_figs/sn2020adw.pdf b/paper_figs/sn2020adw.pdf new file mode 100755 index 0000000..e20cd2a Binary files /dev/null and b/paper_figs/sn2020adw.pdf differ diff --git a/paper_figs/sn2020cdj_SLR.pdf b/paper_figs/sn2020cdj_SLR.pdf new file mode 100755 index 0000000..e3e8491 Binary files /dev/null and b/paper_figs/sn2020cdj_SLR.pdf differ diff --git a/paper_figs/sn2020cdj_diff_diag.pdf b/paper_figs/sn2020cdj_diff_diag.pdf new file mode 100755 index 0000000..518c5c3 Binary files /dev/null and b/paper_figs/sn2020cdj_diff_diag.pdf differ diff --git a/paper_figs/sn2020cdj_disp.pdf b/paper_figs/sn2020cdj_disp.pdf new file mode 100755 index 0000000..90f67b9 Binary files /dev/null and b/paper_figs/sn2020cdj_disp.pdf differ diff --git a/paper_figs/sn2020cdj_disp_corr.pdf b/paper_figs/sn2020cdj_disp_corr.pdf new file mode 100755 index 0000000..973b3f8 Binary files /dev/null and b/paper_figs/sn2020cdj_disp_corr.pdf differ diff --git a/paper_figs/sn2020cdjcal_sources.pdf b/paper_figs/sn2020cdjcal_sources.pdf new file mode 100755 index 0000000..727cf45 Binary files /dev/null and b/paper_figs/sn2020cdjcal_sources.pdf differ diff --git a/paper_figs/sn2020cdjcal_zp.pdf b/paper_figs/sn2020cdjcal_zp.pdf new file mode 100755 index 0000000..cd2fbba Binary files /dev/null and b/paper_figs/sn2020cdjcal_zp.pdf differ diff --git a/paper_figs/sn2020yzo_SLR.pdf b/paper_figs/sn2020yzo_SLR.pdf new file mode 100755 index 0000000..6fdef99 Binary files /dev/null and b/paper_figs/sn2020yzo_SLR.pdf differ diff --git a/paper_figs/sn2020yzo_diff_diag.pdf b/paper_figs/sn2020yzo_diff_diag.pdf new file mode 100755 index 0000000..65359c5 Binary files /dev/null and b/paper_figs/sn2020yzo_diff_diag.pdf differ diff --git a/paper_figs/sn2020yzo_disp.pdf b/paper_figs/sn2020yzo_disp.pdf new file mode 100755 index 0000000..7c3dc0b Binary files /dev/null and b/paper_figs/sn2020yzo_disp.pdf differ diff --git a/paper_figs/sn2020yzo_disp_corr.pdf b/paper_figs/sn2020yzo_disp_corr.pdf new file mode 100755 index 0000000..de5f10c Binary files /dev/null and b/paper_figs/sn2020yzo_disp_corr.pdf differ diff --git a/paper_figs/sn2020yzocal_sources.pdf b/paper_figs/sn2020yzocal_sources.pdf new file mode 100755 index 0000000..ac8285e Binary files /dev/null and b/paper_figs/sn2020yzocal_sources.pdf differ diff --git a/paper_figs/sn2020yzocal_zp.pdf b/paper_figs/sn2020yzocal_zp.pdf new file mode 100755 index 0000000..5d2fc39 Binary files /dev/null and b/paper_figs/sn2020yzocal_zp.pdf differ diff --git a/paper_figs/sn2021dbg.pdf b/paper_figs/sn2021dbg.pdf new file mode 100755 index 0000000..54b9a22 Binary files /dev/null and b/paper_figs/sn2021dbg.pdf differ diff --git a/paper_figs/variable_SLR.pdf b/paper_figs/variable_SLR.pdf new file mode 100755 index 0000000..b1fa6e1 Binary files /dev/null and b/paper_figs/variable_SLR.pdf differ diff --git a/paper_figs/variable_diff_diag.pdf b/paper_figs/variable_diff_diag.pdf new file mode 100755 index 0000000..b751ce3 Binary files /dev/null and b/paper_figs/variable_diff_diag.pdf differ diff --git a/paper_figs/variable_disp.pdf b/paper_figs/variable_disp.pdf new file mode 100755 index 0000000..1ecbe5b Binary files /dev/null and b/paper_figs/variable_disp.pdf differ diff --git a/paper_figs/variablecal_sources.pdf b/paper_figs/variablecal_sources.pdf new file mode 100755 index 0000000..89481ec Binary files /dev/null and b/paper_figs/variablecal_sources.pdf differ diff --git a/paper_figs/variablecal_zp.pdf b/paper_figs/variablecal_zp.pdf new file mode 100755 index 0000000..9f3f8cc Binary files /dev/null and b/paper_figs/variablecal_zp.pdf differ diff --git a/setup.py b/setup.py index 9f277f7..fa868c2 100755 --- a/setup.py +++ b/setup.py @@ -24,23 +24,19 @@ # What packages are required for this module to be executed? REQUIRED = ['lightkurve>=2.0.0', - 'numpy>=1.20.0', + 'numpy', 'photutils>=1.4', 'pandas', 'scipy!=1.4.0,!=1.4.1,>=0.19.0', 'astropy', - 'astroquery', 'joblib', + 'multiprocess', 'scikit-image', - 'scikit-learn', - 'Pillow', - 'requests', - 'sep', - 'tqdm', 'alerce', 'tess-point', 'tabulate', - 'TESS_PRF'] + 'TESS_PRF', + 'opencv-python'] # What packages are optional? EXTRAS = { diff --git a/tessreduce/R_load.py b/tessreduce/R_load.py index 6545bba..7d2d201 100755 --- a/tessreduce/R_load.py +++ b/tessreduce/R_load.py @@ -45,7 +45,7 @@ def R_val(band,g=None,r=None,gr=None,ext=0,system='ps1'): gr = g-r if (gr is None) | np.isnan(gr).all(): - Rb = R[band]['coeff'][1] + Rb = R[band]['coeff'][1] else: Rr0 = R[band]['coeff'][1] Rg0 = R[band]['coeff'][1] @@ -53,7 +53,7 @@ def R_val(band,g=None,r=None,gr=None,ext=0,system='ps1'): gr_int = gr - ext*(Rg0 - Rr0) vals = R[band]['coeff'] - Rb = line(gr_int,vals[0],vals[1]) + Rb = line(gr_int,vals[0],vals[1]) Rb_e = R[band]['std'] return Rb, Rb_e diff --git a/tessreduce/__init__.py b/tessreduce/__init__.py index df1e664..25f797e 100755 --- a/tessreduce/__init__.py +++ b/tessreduce/__init__.py @@ -1,5 +1,2 @@ -from .tessreduce import * -#from .background_separator import TESSBackgroundSeparator -from .adaptive_background import AdaptiveBackground, adaptive_medfilt_3d, get_tessvectors - +from .tessreduce import * from .__version__ import __version__ diff --git a/tessreduce/adaptive_background.py b/tessreduce/adaptive_background.py deleted file mode 100644 index b636cf2..0000000 --- a/tessreduce/adaptive_background.py +++ /dev/null @@ -1,650 +0,0 @@ -""" -Adaptive median-filter background smoother for TESS FFI background cubes. - -Public API ----------- -AdaptiveBackground(data, time, sector, camera, data_path=None) - Main class. Fetches Earth/Moon angle vectors from TESSVectors (local or - remote) and exposes a .smooth() method. - -get_tessvectors(sector, camera, data_path=None) - Retrieve a TESSVectors CSV as a pandas DataFrame, checking data_path - before falling back to the remote HEASARC server. - -adaptive_medfilt_3d(data, time, ...) - Low-level 3-D adaptive median filter. Can be used directly with - pre-fetched angle arrays or without angles. -""" - -import os -import numpy as np -import pandas as pd -from scipy.ndimage import median_filter, percentile_filter, uniform_filter -from scipy.signal import savgol_filter -from joblib import Parallel, delayed - - -# ── TESSVectors helpers ──────────────────────────────────────────────────────── - -_TESSVECTORS_REMOTE = ( - "https://heasarc.gsfc.nasa.gov/docs/tess/data/TESSVectors/Vectors/" - "FFI_Cadence/TessVectors_S{sector:03d}_C{camera}_FFI.csv" -) -_TESSVECTORS_FNAME = "TessVectors_S{sector:03d}_C{camera}_FFI.csv" - - -def get_tessvectors(sector, camera, data_path=None): - """Return a TESSVectors DataFrame for *sector* / *camera*. - - Parameters - ---------- - sector : int - camera : int (1–4) - data_path : str or None - Local directory to check for pre-downloaded TESSVectors CSV files - before attempting a remote download. - - Returns - ------- - pandas.DataFrame - Columns include ``MidTime`` (BTJD), ``Earth_Camera_Angle``, - ``Moon_Camera_Angle``. - """ - fname = _TESSVECTORS_FNAME.format(sector=sector, camera=camera) - - if data_path is not None: - local = os.path.join(data_path, fname) - if os.path.isfile(local): - return pd.read_csv(local, comment='#', index_col=False) - - url = _TESSVECTORS_REMOTE.format(sector=sector, camera=camera) - try: - df = pd.read_csv(url, comment='#', index_col=False) - except: - df = None - return df - - -def _interpolate_angles(time_mjd, df): - """Interpolate Earth/Moon camera angles onto *time_mjd* (MJD). - - TESSVectors MidTime is BTJD (BJD − 2457000); MJD = BTJD + 57000. - """ - btjd = time_mjd - 56999.5 - vec_t = df['MidTime'].values - earth = np.interp(btjd, vec_t, df['Earth_Camera_Angle'].values) - moon = np.interp(btjd, vec_t, df['Moon_Camera_Angle'].values) - return earth, moon - - -# ── Internal helpers ─────────────────────────────────────────────────────────── - -def _make_odd(x): - x = max(int(x), 3) - return x if x % 2 == 1 else x + 1 - - -def _get_segments(time, gap_thresh): - dt = np.diff(time) - median_dt = np.median(dt) - breaks = np.where(dt > gap_thresh * median_dt)[0] + 1 - starts = np.concatenate([[0], breaks]) - ends = np.concatenate([breaks, [len(time)]]) - return list(zip(starts.tolist(), ends.tolist())) - - -def _block_reduce(arr, bs): - """Block-average (T, X, Y) spatially by factor *bs*, discarding edge pixels - that don't fill a complete block.""" - T, X, Y = arr.shape - Xd, Yd = X // bs, Y // bs - return (arr[:, :Xd * bs, :Yd * bs] - .reshape(T, Xd, bs, Yd, bs) - .mean(axis=(2, 4)) - .astype(arr.dtype)) - - -def _upsample_nearest(arr, X, Y, bs): - """Nearest-neighbour upsample (T, Xd, Yd) back to (T, X, Y).""" - up = np.repeat(np.repeat(arr, bs, axis=1), bs, axis=2) - if up.shape[1] < X: - up = np.concatenate([up, up[:, -1:, :]], axis=1) - if up.shape[2] < Y: - up = np.concatenate([up, up[:, :, -1:]], axis=2) - return up[:, :X, :Y] - - -# ── Core adaptive filter ─────────────────────────────────────────────────────── - -def adaptive_medfilt_3d( - data, - time=None, - gap_thresh=3.0, - w_min=3, - w_max=51, - grad_smooth_window=11, - low_pct=5, - high_pct=80, - per_pixel_norm=True, - n_levels=7, - n_jobs=1, - metric='deviation', - coarse_windows=(11, 21, 51, 101), - combined_weight=0.5, - local_std_window=21, - local_norm_window=201, - brightness_sigma=2.0, - window_smooth_size=1, - earth_angle=None, - moon_angle=None, - scatter_angle_thresh=50.0, - block_size=1, - sigma_clip=5.0, -): - """Adaptive median filter for a (T, X, Y) background cube. - - Parameters - ---------- - data : array (T, X, Y) - time : array (T,), optional - Frame mid-times. Defaults to integer frame indices. - gap_thresh : float - Gap declared where ``dt > gap_thresh * median_dt``. Smoothing never - crosses a gap boundary. - w_min, w_max : int - Min / max (odd) filter window sizes along the time axis. - metric : {'deviation', 'gradient', 'local_std', 'combined'} - coarse_windows : tuple of int - Baseline window sizes for the deviation metric. - brightness_sigma : float - Sigma for sigma-clipping the frame-mean distribution to define the - background brightness level. - earth_angle, moon_angle : array (T,) or None - Camera angles (degrees) for scattered-light masking. - scatter_angle_thresh : float - Frames with ``min(earth, moon) < scatter_angle_thresh`` are treated as - scatter-contaminated; all deviation scales are zeroed (→ w_max) in - scatter-free faint frames when scatter is detected. - n_jobs : int - Parallel jobs. ``-1`` uses all available cores. - - Returns - ------- - smoothed : array (T, X, Y) - windows : array (T, X, Y), int - variability : array (T, X, Y), float - windows_pre_smooth : array (T, X, Y), int - """ - data = np.asarray(data, dtype=np.float32) - T, X, Y = data.shape - - if time is None: - time = np.arange(T, dtype=float) - time = np.asarray(time, dtype=float) - - segments = _get_segments(time, gap_thresh) - - nan_mask = ~np.isfinite(data) - data_filled = data.copy() - if nan_mask.any(): - flat = data_filled.reshape(T, -1) - for s, e in segments: - t_seg = time[s:e] - seg_flat = flat[s:e] - bad = ~np.isfinite(seg_flat) - if not bad.any(): - continue - all_bad = bad.all(axis=0) - seg_flat[:, all_bad] = 0.0 - partial = bad.any(axis=0) & ~all_bad - for j in np.where(partial)[0]: - ts = seg_flat[:, j] - m = np.isfinite(ts) - seg_flat[:, j] = np.interp(t_seg, t_seg[m], ts[m]) - - gw = _make_odd(grad_smooth_window) - - if metric in ('gradient', 'combined'): - grad = np.gradient(data_filled, time, axis=0) - for s, e in segments: - if s > 0: - grad[s] = 0.0 - if e < T: - grad[e - 1] = 0.0 - grad_var = np.zeros_like(grad) - for s, e in segments: - seg = grad[s:e] - if e - s >= gw: - grad_var[s:e] = np.abs(median_filter(seg, size=(gw, 1, 1), mode='reflect')) - else: - grad_var[s:e] = np.abs(seg) - - if metric in ('deviation', 'combined'): - scales = [coarse_windows] if isinstance(coarse_windows, int) else list(coarse_windows) - - data_metric = _block_reduce(data_filled, block_size) if block_size > 1 else data_filled - - def _compute_dev(cw, data_metric=data_metric, segments=segments, gw=gw): - dev = np.zeros_like(data_metric) - for s, e in segments: - seg = data_metric[s:e] - n = e - s - w = _make_odd(min(cw, n if n % 2 == 1 else n - 1)) - coarse_seg = median_filter(seg, size=(w, 1, 1), mode='reflect') - diff = np.abs(seg - coarse_seg) - dw = _make_odd(min(gw, n if n % 2 == 1 else n - 1)) - dev[s:e] = median_filter(diff, size=(dw, 1, 1), mode='reflect') - return dev - - all_devs = Parallel(n_jobs=n_jobs)(delayed(_compute_dev)(cw) for cw in scales) - - _frame_mean = data_metric.mean(axis=(1, 2)) - _clipped = _frame_mean[np.isfinite(_frame_mean)] - for _ in range(5): - _med = np.median(_clipped) - _std = np.std(_clipped) - if _std == 0: - break - _clipped = _clipped[np.abs(_clipped - _med) < brightness_sigma * _std] - brightness_threshold = float(np.mean(_clipped)) + brightness_sigma * float(np.std(_clipped)) - bright_mask = (_frame_mean > brightness_threshold).astype(float)[:, np.newaxis, np.newaxis] - - _frame_active = _frame_mean > brightness_threshold - _use_stable_mask = False - if earth_angle is not None or moon_angle is not None: - _ea = np.asarray(earth_angle, dtype=float) if earth_angle is not None else np.full(T, np.inf) - _ma = np.asarray(moon_angle, dtype=float) if moon_angle is not None else np.full(T, np.inf) - _scatter_free = np.minimum(_ea, _ma) > scatter_angle_thresh - if (~_scatter_free).any(): - _stable_frame = _scatter_free & ~_frame_active - _stable_mask = _stable_frame[:, np.newaxis, np.newaxis].astype(float) - _use_stable_mask = True - - lnw = _make_odd(local_norm_window) - - def _compute_norm(i_dev, bright_mask=bright_mask, segments=segments, - lnw=lnw, low_pct=low_pct, high_pct=high_pct): - i, dev = i_dev - scale_floor = max(np.nanpercentile(dev, 75), 1e-10) - g_lo = np.zeros_like(dev) - g_hi = np.zeros_like(dev) - for s, e in segments: - seg_v = dev[s:e] - n = e - s - lw = _make_odd(min(lnw, n if n % 2 == 1 else n - 1)) - g_lo[s:e] = percentile_filter(seg_v, low_pct, size=(lw, 1, 1), mode='reflect') - g_hi[s:e] = percentile_filter(seg_v, high_pct, size=(lw, 1, 1), mode='reflect') - dg = np.maximum(g_hi - g_lo, scale_floor) - norm_scale = np.clip((dev - g_lo) / dg, 0.0, 1.0) - if i == 0: - norm_scale = norm_scale * bright_mask - return norm_scale - - scale_norms = Parallel(n_jobs=n_jobs)( - delayed(_compute_norm)((i, dev)) for i, dev in enumerate(all_devs) - ) - - if _use_stable_mask: - scale_norms = [ns * (1.0 - _stable_mask) for ns in scale_norms] - - dev_var = np.max(np.stack(scale_norms), axis=0) - - if metric in ('local_std', 'combined'): - lsw = _make_odd(local_std_window) - lstd_var = np.zeros_like(data_filled) - for s, e in segments: - seg = data_filled[s:e] - n = e - s - w = _make_odd(min(lsw, n if n % 2 == 1 else n - 1)) - m = uniform_filter(seg, size=(w, 1, 1), mode='reflect') - m2 = uniform_filter(seg ** 2, size=(w, 1, 1), mode='reflect') - lstd_var[s:e] = np.sqrt(np.maximum(m2 - m ** 2, 0)) - - def _norm01(x): - lo, hi = np.nanpercentile(x, 1), np.nanpercentile(x, 99) - return np.clip((x - lo) / (hi - lo + 1e-30), 0, 1) - - if metric == 'gradient': - variability = grad_var - elif metric == 'local_std': - variability = lstd_var - elif metric == 'combined': - variability = (1 - combined_weight) * _norm01(grad_var) + combined_weight * _norm01(lstd_var) - elif metric == 'deviation': - variability = dev_var - else: - raise ValueError( - f"metric must be 'gradient', 'deviation', 'local_std', or 'combined', got '{metric}'" - ) - - if metric == 'deviation': - norm = dev_var - elif local_norm_window is not None: - lnw = _make_odd(local_norm_window) - g_lo = np.zeros_like(variability) - g_hi = np.zeros_like(variability) - for s, e in segments: - seg_var = variability[s:e] - n = e - s - w = _make_odd(min(lnw, n if n % 2 == 1 else n - 1)) - g_lo[s:e] = percentile_filter(seg_var, low_pct, size=(w, 1, 1)) - g_hi[s:e] = percentile_filter(seg_var, high_pct, size=(w, 1, 1)) - dg = np.where((g_hi - g_lo) > 0, g_hi - g_lo, 1.0) - norm = np.clip((variability - g_lo) / dg, 0.0, 1.0) - elif per_pixel_norm: - g_lo = np.nanpercentile(variability, low_pct, axis=0, keepdims=True) - g_hi = np.nanpercentile(variability, high_pct, axis=0, keepdims=True) - dg = np.where((g_hi - g_lo) > 0, g_hi - g_lo, 1.0) - norm = np.clip((variability - g_lo) / dg, 0.0, 1.0) - else: - g_lo = np.nanpercentile(variability, low_pct) - g_hi = np.nanpercentile(variability, high_pct) - dg = np.where((g_hi - g_lo) > 0, g_hi - g_lo, 1.0) - norm = np.clip((variability - g_lo) / dg, 0.0, 1.0) - - raw_w = w_max - norm * (w_max - w_min) - windows = np.round(raw_w).astype(int) - windows += (1 - windows % 2) - windows = np.clip(windows, _make_odd(w_min), _make_odd(w_max)) - - windows_pre_smooth = windows.copy() - - if window_smooth_size > 1: - wsz = _make_odd(window_smooth_size) - smoothed_win = np.empty_like(windows, dtype=float) - for s, e in segments: - n = e - s - w = _make_odd(min(wsz, n if n % 2 == 1 else n - 1)) - smoothed_win[s:e] = median_filter(windows[s:e].astype(float), size=(w, 1, 1), mode='reflect') - windows = np.round(smoothed_win).astype(int) - windows += (1 - windows % 2) - windows = np.clip(windows, _make_odd(w_min), _make_odd(w_max)) - - if block_size > 1: - variability = _upsample_nearest(variability, X, Y, block_size) - windows_pre_smooth = _upsample_nearest(windows_pre_smooth, X, Y, block_size) - windows = _upsample_nearest(windows, X, Y, block_size) - - levels = np.unique([_make_odd(int(round(w))) for w in np.linspace(w_min, w_max, n_levels)]) - windows_quantized = levels[np.argmin(np.abs(windows[..., np.newaxis] - levels), axis=-1)] - - result = np.empty((T, X, Y), dtype=np.float32) - for s, e in segments: - seg_data = data_filled[s:e] - seg_wins = windows_quantized[s:e] - seg_levels = np.unique(seg_wins) - - def _smooth_seg(w, seg=seg_data): - return w, median_filter(seg, size=(w, 1, 1), mode='reflect') - - for w, smoothed_w in Parallel(n_jobs=n_jobs)(delayed(_smooth_seg)(w) for w in seg_levels): - result[s:e][seg_wins == w] = smoothed_w[seg_wins == w] - - if sigma_clip is not None: - frame_resid = np.nanmedian(np.abs(result - data_filled), axis=(1, 2)) - typical = np.nanmedian(frame_resid) - mad_frame = np.nanmedian(np.abs(frame_resid - typical)) - frame_outlier = frame_resid > typical + sigma_clip * 1.4826 * mad_frame - result[frame_outlier] = data_filled[frame_outlier] - - result[nan_mask] = np.nan - return result, windows, variability, windows_pre_smooth - - -# ── Savitzky-Golay smoother ──────────────────────────────────────────────────── - -def savgol_smooth_3d(data, time=None, gap_thresh=3.0, window_length=None, polyorder=2, sigma_clip=5.0): - """Apply a Savitzky-Golay filter along the time axis of a (T, X, Y) cube. - - Smoothing is applied independently per segment (gaps are not crossed). - Per-pixel temporal outliers are sigma-clipped and interpolated over before - filtering, preventing transient signals (e.g. asteroids) from biasing the - smooth background estimate. NaNs are handled the same way. - - Parameters - ---------- - data : array (T, X, Y) - time : array (T,), optional - gap_thresh : float - window_length : int or None - Must be odd; reduced automatically if shorter than a segment. - If None (default), computed from the cadence to span 6 hours. - polyorder : int - sigma_clip : float - Per-pixel frames more than sigma_clip * MAD above the median are - replaced by interpolation before smoothing. Set to None to disable. - - Returns - ------- - smoothed : array (T, X, Y) - """ - data = np.asarray(data, dtype=np.float32) - T, X, Y = data.shape - - if time is None: - time = np.arange(T, dtype=float) - time = np.asarray(time, dtype=float) - - segments = _get_segments(time, gap_thresh) - - nan_mask = ~np.isfinite(data) - data_filled = data.copy() - - if nan_mask.any(): - flat = data_filled.reshape(T, -1) - for s, e in segments: - t_seg = time[s:e] - seg_flat = flat[s:e] - bad = ~np.isfinite(seg_flat) - if not bad.any(): - continue - all_bad = bad.all(axis=0) - seg_flat[:, all_bad] = 0.0 - for j in np.where(bad.any(axis=0) & ~all_bad)[0]: - ts = seg_flat[:, j] - m = np.isfinite(ts) - seg_flat[:, j] = np.interp(t_seg, t_seg[m], ts[m]) - - if window_length is None: - cadence = float(np.median(np.diff(time))) if len(time) > 1 else 1.0 - n_frames = max(3, int(round(0.25 / cadence))) # 6 hours = 0.25 days - window_length = n_frames if n_frames % 2 == 1 else n_frames + 1 - wl = window_length if window_length % 2 == 1 else window_length + 1 - - def _apply_savgol(arr): - out = arr.copy() - for s, e in segments: - n = e - s - w = wl - while w >= n: - w -= 2 - if w < polyorder + 1: - continue - out[s:e] = savgol_filter(arr[s:e], window_length=w, polyorder=polyorder, axis=0) - return out - - # First pass - first_pass = _apply_savgol(data_filled) - - # Identify outliers from first-pass residuals and interpolate over them - if sigma_clip is not None: - resid = data_filled - first_pass - resid_flat = resid.reshape(T, -1) - mad = np.nanmedian(np.abs(resid_flat - np.nanmedian(resid_flat, axis=0)), axis=0) - robust_std = 1.4826 * mad - # clip both positive and negative outliers - outlier = np.abs(resid_flat) > sigma_clip * robust_std - data_filled2 = data_filled.copy().reshape(T, -1) - data_filled2[outlier] = np.nan - for s, e in segments: - t_seg = time[s:e] - seg_flat = data_filled2[s:e] - bad = ~np.isfinite(seg_flat) - if not bad.any(): - continue - all_bad = bad.all(axis=0) - seg_flat[:, all_bad] = 0.0 - for j in np.where(bad.any(axis=0) & ~all_bad)[0]: - ts = seg_flat[:, j] - m = np.isfinite(ts) - seg_flat[:, j] = np.interp(t_seg, t_seg[m], ts[m]) - data_filled2 = data_filled2.reshape(T, X, Y) - result = _apply_savgol(data_filled2) - else: - result = first_pass - - # Per-frame fallback: if the whole frame deviates significantly from the - # smooth (i.e. the smooth has smeared a sharp scattered-light transition), - # restore the original unsmoothed value for that frame. - frame_resid = np.nanmedian(np.abs(result - data_filled), axis=(1, 2)) - typical = np.nanmedian(frame_resid) - mad_frame = np.nanmedian(np.abs(frame_resid - typical)) - frame_outlier = frame_resid > typical + sigma_clip * 1.4826 * mad_frame - result[frame_outlier] = data_filled[frame_outlier] - - result[nan_mask] = np.nan - return result - - -# ── Main class ───────────────────────────────────────────────────────────────── - -class AdaptiveBackground: - """Adaptive median-filter smoother for a TESS background cube. - - Parameters - ---------- - data : array (T, X, Y) - Background flux cube. - time : array (T,) - Frame mid-times in MJD (BJD − 2400000.5). - sector : int - TESS sector number. Used to fetch TESSVectors angle data. - camera : int - TESS camera number (1–4). - data_path : str or None - Local directory containing TESSVectors CSV files. Checked before - downloading from the remote HEASARC server. If ``None``, always - downloads. - - Attributes - ---------- - smoothed : array (T, X, Y) or None - Smoothed background, populated after calling :meth:`smooth`. - windows : array (T, X, Y) or None - Adaptive window sizes, populated after :meth:`smooth`. - variability : array (T, X, Y) or None - Normalised variability metric, populated after :meth:`smooth`. - earth_angle, moon_angle : array (T,) - Camera angles interpolated from TESSVectors (available after init). - - Examples - -------- - >>> ab = AdaptiveBackground(bkg_cube, time_mjd, sector=34, camera=1) - >>> ab.smooth() - >>> smoothed = ab.smoothed - """ - - def __init__(self, data, time, sector, camera, data_path=None, n_jobs=-1, block_size=5): - self.data = np.asarray(data, dtype=np.float32) - self.time = np.asarray(time, dtype=float) - self.sector = int(sector) - self.camera = int(camera) - self.data_path = data_path - self.n_jobs = n_jobs - self.block_size = int(block_size) - - self.smoothed = None - self.windows = None - self.variability = None - self._windows_pre_smooth = None - self.earth_angle = None - self.moon_angle = None - - self._df = get_tessvectors(sector, camera, data_path=data_path) - if self._df is not None: - self.earth_angle, self.moon_angle = _interpolate_angles(self.time, self._df) - - def smooth( - self, - method='savgol', - savgol_window=None, - savgol_polyorder=2, - gap_thresh=3.0, - w_min=3, - w_max=51, - grad_smooth_window=11, - low_pct=5, - high_pct=80, - per_pixel_norm=True, - n_levels=7, - n_jobs=None, - metric='deviation', - coarse_windows=(11, 21, 51, 101), - combined_weight=0.5, - local_std_window=21, - local_norm_window=201, - brightness_sigma=2.0, - window_smooth_size=1, - scatter_angle_thresh=50.0, - block_size=None, - sigma_clip=5.0, - ): - """Run background smoothing and store results on the instance. - - Parameters - ---------- - method : {'savgol', 'adaptive'} - Smoothing method. ``'savgol'`` applies a Savitzky-Golay filter; - ``'adaptive'`` uses the adaptive median filter. - savgol_window : int - Window length for the Savitzky-Golay filter (must be odd). - savgol_polyorder : int - Polynomial order for the Savitzky-Golay filter. - - All remaining parameters are passed to :func:`adaptive_medfilt_3d` - when ``method='adaptive'``. Returns ``self`` for method chaining. - """ - if method == 'savgol': - self.smoothed = savgol_smooth_3d( - self.data, - time=self.time, - gap_thresh=gap_thresh, - window_length=savgol_window, - polyorder=savgol_polyorder, - ) - self.windows = None - self.variability = None - self._windows_pre_smooth = None - else: - if n_jobs is None: - n_jobs = self.n_jobs - if block_size is None: - block_size = self.block_size - self.smoothed, self.windows, self.variability, self._windows_pre_smooth = ( - adaptive_medfilt_3d( - self.data, - time=self.time, - gap_thresh=gap_thresh, - w_min=w_min, - w_max=w_max, - grad_smooth_window=grad_smooth_window, - low_pct=low_pct, - high_pct=high_pct, - per_pixel_norm=per_pixel_norm, - n_levels=n_levels, - n_jobs=n_jobs, - metric=metric, - coarse_windows=coarse_windows, - combined_weight=combined_weight, - local_std_window=local_std_window, - local_norm_window=local_norm_window, - brightness_sigma=brightness_sigma, - window_smooth_size=window_smooth_size, - earth_angle=self.earth_angle, - moon_angle=self.moon_angle, - scatter_angle_thresh=scatter_angle_thresh, - block_size=block_size, - sigma_clip=sigma_clip, - ) - ) - return self diff --git a/tessreduce/background.py b/tessreduce/background.py index 751c806..3db1a0d 100755 --- a/tessreduce/background.py +++ b/tessreduce/background.py @@ -1,28 +1,22 @@ -import numpy as np -import multiprocessing -from copy import deepcopy -from scipy.ndimage import gaussian_filter -from scipy.interpolate import griddata -from astropy.stats import sigma_clip, sigma_clipped_stats -from joblib import Parallel, delayed - -from .helpers import strip_units, Smooth_bkg class Background(): - def __init__(self, flux, mask, buffer=3, extrapolate=True, parallel=True): + def __init__(self, flux, mask, buffer=3, extrapolate = True, parallel = True): self.flux = flux - self.mask = mask + self.mask = mask self.buffer = buffer self.extrapolate = extrapolate - self.parallel = parallel + self.parallel = True self.size = self._check_size() + #calculate self.smooth_bkg = np.zeros_like(flux) self.qe = np.zeros_like(flux) self.bkg = np.zeros_like(flux) + + def _check_size(self): size = self.flux.shape[1:] if (size < 30).any(): @@ -32,21 +26,26 @@ def _check_size(self): def _smooth_bkg(self, index): """ - Interpolate over the masked objects to derive a background estimate. + Interpolate over the masked objects to derive a background estimate. Parameters ---------- data : array - A single image - - extrapolate : bool - Switch for using extrapolation in the background. + A single image + + extrapolate: Bool + switch for using extrapolation in the background Returns ------- - estimate : array - An estimate of the smooth background in the TESS image. + estimate : array + an estimate of the smooth background in the TESS image + + bitmask : array + an array indicating where extrapolation was used + """ + #data[data == 0] = np.nan data = self.flux * self.mask[index] if (~np.isnan(data)).any(): @@ -54,71 +53,76 @@ def _smooth_bkg(self, index): y = np.arange(0, data.shape[0]) arr = np.ma.masked_invalid(data) xx, yy = np.meshgrid(x, y) + #get only the valid values x1 = xx[~arr.mask] y1 = yy[~arr.mask] newarr = arr[~arr.mask] + #print(x1,y1) if (len(x1) > 10) & (len(y1) > 10): estimate = griddata((x1, y1), newarr.ravel(), - (xx, yy), method='linear') + (xx, yy),method='linear') nearest = griddata((x1, y1), newarr.ravel(), - (xx, yy), method='nearest') + (xx, yy),method='nearest') if self.extrapolate: estimate[np.isnan(estimate)] = nearest[np.isnan(estimate)] - estimate = gaussian_filter(estimate, 1.5) + + estimate = gaussian_filter(estimate,1.5) + #estimate = median_filter(estimate,5) else: - estimate = np.zeros_like(data) * np.nan + estimate = np.zeros_like(data) * np.nan else: - estimate = np.zeros_like(data) * np.nan + estimate = np.zeros_like(data) #* np.nan return estimate def _smooth_wrapper(self): m = (self.mask == 0) * 1. - m[m == 0] = np.nan + m[m==0] = np.nan flux = strip_units(self.flux) + bkg_smth = np.zeros_like(flux) * np.nan if self.parallel: num_cores = multiprocessing.cpu_count() - bkg_smth = Parallel(n_jobs=num_cores)( - delayed(Smooth_bkg)(frame) for frame in flux * m) + bkg_smth = Parallel(n_jobs=num_cores)(delayed(self.Smooth_bkg)(frame) for frame in flux*m) else: - bkg_smth = np.zeros_like(flux) * np.nan for i in range(flux.shape[0]): - bkg_smth[i] = Smooth_bkg(flux[i] * m) + bkg_smth[i] = Smooth_bkg(flux[i]*m) self.smooth_bkg = bkg_smth - + def _strap_wrapper(self): strap = (self.mask == 4) * 1.0 - strap[strap == 0] = np.nan - if len(strap.shape) == 3: + strap[strap==0] = np.nan + # check if its a time varying mask + if len(strap.shape) == 3: strap = strap[self.ref_ind] mask = ((self.mask & 1) == 0) * 1.0 - mask[mask == 0] = np.nan + mask[mask==0] = np.nan data = strip_units(self.flux) * mask - bkg_smth = self.smooth_bkg # was incorrectly a bare name reference qes = np.zeros_like(bkg_smth) * np.nan for i in range(data.shape[0]): - s = (data[i] * strap) / bkg_smth[i] - s[s > np.percentile(s[np.isfinite(s)], 50)] = np.nan + s = (data[i]*strap)/bkg_smth[i] + s[s > np.percentile(s,50)] = np.nan q = np.zeros_like(s) * np.nan for j in range(s.shape[1]): - ind = ~sigma_clip(s[:, j]).mask - q[:, j] = np.nanmedian(abs(s[ind, j])) - q[np.isnan(q)] = 1 + ind = ~sigma_clip(s[:,j]).mask + q[:,j] = np.nanmedian(abs(s[ind,j])) + q[np.isnan(q)] =1 qes[i] = q - self.qe = qes - self.bkg = bkg_smth * qes + bkg = bkg_smth * qes + + self.qe = qes + self.bkg = bkg def _small_background(self): bkg = np.zeros_like(self.flux) flux = strip_units(self.flux) - lim = np.percentile(flux, 10, axis=(1, 2)) - ind = flux > lim[:, np.newaxis, np.newaxis] + lim = np.percentile(flux,10,axis=(1,2)) + ind = flux > lim[:,np.newaxis,np.newaxis] flux[ind] = np.nan - val = np.nanmedian(flux, axis=(1, 2)) - bkg[:, :, :] = val[:, np.newaxis, np.newaxis] + val = np.nanmedian(flux,axis=(1,2)) + bkg[:,:,:] = val[:,np.newaxis,np.newaxis] self.bkg = bkg def calculate(self): @@ -130,3 +134,9 @@ def calculate(self): self._strap_wrapper() else: self._small_background() + + + + + + diff --git a/tessreduce/background_separator.py b/tessreduce/background_separator.py deleted file mode 100644 index 60c35ed..0000000 --- a/tessreduce/background_separator.py +++ /dev/null @@ -1,1534 +0,0 @@ -""" -TESSBackgroundSeparator -======================= -Standalone multi-method background separation for TESS flux cubes (T, X, Y). - -Signal model ------------- - flux[t, x, y] = background[t, x, y] + astrophysical[t, x, y] + noise[t, x, y] - - background – scattered light / instrumental (spatially non-coherent) - astrophysical – localized to source pixels; can contain transients and trends - noise – per-pixel random noise - -Mask convention (tessreduce bit values) ------------------------------------------ - bit 1 – stellar source - bit 2 – saturated source - bit 4 – strap column (variable multiplicative QE) - -Methods -------- - vectors physically-driven regression on Earth/Moon separation angles - savgol adaptive per-pixel Savitzky-Golay (baseline) - gp per-pixel Gaussian Process (RBF kernel, efficient batch solve) - local_pca pixel-level decorrelation using nearby background pixels (PLD-style) - rpca Robust PCA: low-rank background + sparse astrophysical signal - nmf Non-negative Matrix Factorization (requires scikit-learn) - autoenc 1-D temporal convolutional autoencoder (requires PyTorch) - -Flux correction rules ---------------------- - Non-strap pixels : only addition / subtraction (flux − background_model) - Strap columns : division also permitted (flux / QE) -""" - -import warnings -import numpy as np -import matplotlib -import matplotlib.pyplot as plt -from copy import deepcopy -from scipy.signal import savgol_filter -from scipy.linalg import solve as la_solve -from scipy.optimize import nnls -from scipy.spatial import cKDTree -from scipy.interpolate import griddata - -try: - from sklearn.decomposition import NMF as _NMF - _HAS_SKLEARN = True -except ImportError: - _HAS_SKLEARN = False - -warnings.filterwarnings("ignore", category=RuntimeWarning) - -# figure sizing consistent with tessreduce.py -fig_width_pt = 240.0 -_ipt = 1.0 / 72.27 -fig_width = fig_width_pt * _ipt - - -# ── module-level helpers ────────────────────────────────────────────────────── - -def _nan_interp_axis0(cube: np.ndarray) -> np.ndarray: - """Fill NaNs along axis=0 via linear interpolation per pixel.""" - out = cube.copy() - T = cube.shape[0] - x_all = np.arange(T, dtype=float) - for idx in np.ndindex(cube.shape[1:]): - ts = cube[(slice(None),) + idx] - good = np.isfinite(ts) - if good.sum() < 2: - out[(slice(None),) + idx] = 0.0 - continue - out[(slice(None),) + idx] = np.interp(x_all, x_all[good], ts[good]) - return out - - -def _make_odd(x: int) -> int: - x = max(int(x), 3) - return x if x % 2 == 1 else x + 1 - - -# ── main class ──────────────────────────────────────────────────────────────── - -class TESSBackgroundSeparator: - """ - Separate astrophysical signal from background in a TESS flux cube. - - Parameters - ---------- - flux : ndarray (T, X, Y) - Raw pixel flux cube in e-/s. - time : ndarray (T,) - Timestamps in MJD (or any monotonic unit in days). - mask : ndarray int (X, Y) - Pixel classification mask with tessreduce bit values: - bit 1 – stellar source - bit 2 – saturated source - bit 4 – strap column - expand_mask : bool - If True (default), run an additional SEP-based pass to detect - any astrophysical sources not covered by `mask` and add them to - the internal source mask used for background fitting. - expand_sigma : float - Detection threshold (in units of background sigma) for unlabelled - source detection. Default 3.5. - """ - - # ── construction ───────────────────────────────────────────────────────── - - def __init__( - self, - flux: np.ndarray, - time: np.ndarray, - mask: np.ndarray, - expand_mask: bool = True, - expand_sigma: float = 3.5, - ): - self.flux = np.asarray(flux, dtype=float) - self.time = np.asarray(time, dtype=float) - self.mask = np.asarray(mask, dtype=int) - - self._T, self._X, self._Y = self.flux.shape - - # Decode mask bits - self._source_mask = ((self.mask & 1) | (self.mask & 2)) > 0 # stars + saturated - self._strap_mask = (self.mask & 4) > 0 # strap columns - - # Background pixels are non-source, non-strap - self._bkg_mask = ~self._source_mask & ~self._strap_mask - - # Optionally expand source mask with SEP-based detection - self._unlabelled_mask = np.zeros((self._X, self._Y), dtype=bool) - if expand_mask: - self._unlabelled_mask = self._detect_unlabelled_sources(expand_sigma) - self._bkg_mask &= ~self._unlabelled_mask - - # Storage - self._backgrounds: dict = {} - self._astro: dict = {} - self._qe: dict = {} # strap QE arrays keyed by strap column index - - # ── strap correction ───────────────────────────────────────────────────── - - def correct_straps( - self, - smooth_window_frac: float = 0.1, - min_smooth_window: int = 7, - gap_thresh: float = 0.5, - plot: bool = False, - ) -> np.ndarray: - """ - Estimate and remove the variable multiplicative quantum efficiency (QE) - of strap columns (mask bit 4). - - For each strap column *c*: - - 1. Identify background rows in *c* (non-source, non-strap pixels). - 2. Estimate the expected background at each strap pixel by linear - interpolation of neighboring non-strap background columns at the - same row. - 3. Compute QE(t, c) = median_row[ flux_strap(t, row, c) - / expected(t, row, c) ] - restricted to background rows. - 4. Smooth QE(t, c) per time segment with Savitzky-Golay. - 5. Divide: flux_corrected(t, :, c) = flux(t, :, c) / QE(t, c) - - The corrected flux is stored back into ``self.flux`` in-place. - The QE arrays are stored in ``self._qe`` (keyed by column index). - - Returns - ------- - flux_corrected : ndarray (T, X, Y) - The strap-corrected flux cube (same object as self.flux after - in-place update). - """ - strap_cols = np.unique(np.where(self._strap_mask)[1]) - if len(strap_cols) == 0: - return self.flux - - non_strap_cols = np.array( - [c for c in range(self._Y) if c not in set(strap_cols)] - ) - if len(non_strap_cols) < 2: - warnings.warn( - "Too few non-strap columns to estimate strap QE. Skipping.", - UserWarning, - ) - return self.flux - - segs = self._segment_indices(gap_thresh) - - # Pre-compute spatial-mean background expected value per non-strap col - # as a function of (T, row) via 1-D column interpolation per row. - # We work row-by-row because the column interpolation is 1-D in col-space. - - for col in strap_cols: - # Background rows in this column: not a source, not another strap type - col_source = self._source_mask[:, col] # (X,) row-wise - bkg_rows = np.where(~col_source)[0] - - if len(bkg_rows) < 3: - # Not enough background rows — skip this column - continue - - # Expected flux at strap column from interpolating non-strap columns - # For each row r and time t: expected = interp(non_strap_cols, flux[t,r,:], col) - # Vectorise over t by working on the non-strap portion of each row. - expected = np.full((self._T, self._X), np.nan) - for row in range(self._X): - # Non-strap flux values along this row - ref_flux = self.flux[:, row, non_strap_cols] # (T, N_ns) - # Linear interpolation at the strap column position - expected[:, row] = np.array([ - np.interp(float(col), non_strap_cols.astype(float), ref_flux[t]) - for t in range(self._T) - ]) - - # QE per time step from background rows only - strap_bkg_flux = self.flux[:, bkg_rows, col] # (T, N_bkg_rows) - exp_bkg_flux = expected[:, bkg_rows] # (T, N_bkg_rows) - - # Ratio per time step; protect against near-zero expected values - with np.errstate(divide='ignore', invalid='ignore'): - ratio = strap_bkg_flux / exp_bkg_flux # (T, N_bkg_rows) - ratio = np.where(np.abs(exp_bkg_flux) < 1e-3, np.nan, ratio) - - qe = np.nanmedian(ratio, axis=1) # (T,) - - # Replace any remaining NaN/zero QE with 1.0 (no correction) - qe = np.where(np.isfinite(qe) & (np.abs(qe) > 1e-3), qe, 1.0) - - # Smooth QE per segment - qe_smooth = qe.copy() - for start, end in segs: - n = end - start - if n < 5: - continue - w = _make_odd(max(int(n * smooth_window_frac), min_smooth_window)) - w = min(w, n if n % 2 == 1 else n - 1) - if w < 3: - continue - seg_qe = qe[start:end] - # Interpolate any residual NaNs before savgol - good = np.isfinite(seg_qe) - if good.sum() < 3: - continue - seg_qe_filled = np.interp( - np.arange(n), np.where(good)[0], seg_qe[good] - ) - qe_smooth[start:end] = savgol_filter(seg_qe_filled, w, 1) - - # Divide strap column by smoothed QE - self.flux[:, :, col] /= qe_smooth[:, np.newaxis] - self._qe[int(col)] = qe_smooth - - if plot: - self._plot_strap_correction(strap_cols) - - return self.flux - - def _plot_strap_correction(self, strap_cols): - """Diagnostic plot for strap QE correction.""" - n_cols = min(len(strap_cols), 4) - fig, axes = plt.subplots(n_cols, 1, - figsize=(1.5 * fig_width, n_cols * fig_width), - sharex=True, squeeze=False) - t = self.time - gap_idx = np.where(np.diff(t) > 0.5)[0] - - def _ng(arr): - a = arr.copy().astype(float) - if len(gap_idx): - a[gap_idx] = np.nan - return a - - for ax, col in zip(axes[:, 0], strap_cols[:n_cols]): - if int(col) in self._qe: - qe = self._qe[int(col)] - ax.plot(t, _ng(qe), lw=1.2, label=f'QE col {col}') - ax.axhline(1.0, color='k', lw=0.8, ls='--') - ax.set_ylabel('QE', fontsize=9) - ax.set_title(f'Strap column {col} — smoothed QE', fontsize=9) - ax.legend(fontsize=8) - axes[-1, 0].set_xlabel('Time (MJD)', fontsize=9) - plt.tight_layout() - plt.show() - - # ── public interface ────────────────────────────────────────────────────── - - def fit(self, method: str = 'local_pca', **kwargs) -> np.ndarray: - """ - Estimate background and return the astrophysical signal cube. - - Parameters - ---------- - method : str - One of 'vectors', 'savgol', 'gp', 'local_pca', 'rpca', 'nmf', - 'autoenc'. - **kwargs - Forwarded to the individual method. - - Returns - ------- - astro : ndarray (T, X, Y) - flux − estimated_background - """ - _dispatch = { - 'vectors' : self._fit_vectors, - 'savgol' : self._fit_savgol, - 'gp' : self._fit_gp, - 'local_pca': self._fit_local_pca, - 'rpca' : self._fit_rpca, - 'nmf' : self._fit_nmf, - 'autoenc' : self._fit_autoenc, - } - if method not in _dispatch: - raise ValueError( - f"Unknown method '{method}'. Choose from {list(_dispatch)}." - ) - bkg = _dispatch[method](**kwargs) - - # ── enforce non-negative residual constraint via inpainting ─────── - # Per-frame noise estimated from background-pixel residuals. - # Where bkg > flux + k*noise, the background was overestimated for - # that pixel-time. Mask those locations and inpaint spatially from - # neighbouring pixels that do satisfy the constraint (same approach - # as tessreduce's inpaint_biharmonic usage). - from skimage.restoration import inpaint as sk_inpaint - - k = 3.0 - resid_bkg = (self.flux - bkg)[:, self._bkg_mask] # (T, N_bkg) - frame_noise = 1.4826 * np.nanmedian( - np.abs(resid_bkg - np.nanmedian(resid_bkg, axis=1, keepdims=True)), - axis=1, - ) # (T,) - - ceiling = self.flux + (k * frame_noise)[:, np.newaxis, np.newaxis] - yx_all = np.array([[y, x] for y in range(self._X) for x in range(self._Y)]) - for t in range(self._T): - bad = bkg[t] > ceiling[t] - if not bad.any(): - continue - good = ~bad - good_yx = np.argwhere(good) - good_vals = bkg[t][good] - # Fast spatial interpolation first - filled_flat = griddata(good_yx, good_vals, yx_all, - method='linear', fill_value=np.nan) - filled = filled_flat.reshape(self._X, self._Y) - # Nearest-neighbour for edge NaNs - still_nan = bad & ~np.isfinite(filled) - if still_nan.any(): - filled_nn = griddata(good_yx, good_vals, yx_all[still_nan.ravel()], - method='nearest') - filled[still_nan] = filled_nn - # Biharmonic only if spatial interpolation still violates ceiling - still_bad = filled > ceiling[t] - if still_bad.any(): - frame_bkg = bkg[t].copy() - frame_bkg[still_bad] = np.nan - filled_bh = sk_inpaint.inpaint_biharmonic( - frame_bkg, still_bad.astype(bool) - ) - filled[still_bad] = filled_bh[still_bad] - bkg[t][bad] = filled[bad] - - self._backgrounds[method] = bkg - self._astro[method] = self.flux - bkg - return self._astro[method] - - def background(self, method: str) -> np.ndarray: - """Return the estimated background cube for a fitted method.""" - if method not in self._backgrounds: - raise KeyError(f"Method '{method}' not fitted. Call fit() first.") - return self._backgrounds[method] - - def scatter(self, method: str) -> float: - """ - RMS scatter of astrophysical residuals measured on background pixels. - Lower is better. - """ - if method not in self._astro: - raise KeyError(f"Method '{method}' not fitted. Call fit() first.") - residuals = self._astro[method][:, self._bkg_mask] - return float(np.sqrt(np.nanmean(residuals ** 2))) - - def compare(self, methods=None) -> dict: - """Return {method: scatter_rms} for all fitted (or listed) methods.""" - if methods is None: - methods = list(self._backgrounds) - return {m: self.scatter(m) for m in methods if m in self._backgrounds} - - # ── diagnostic plots ────────────────────────────────────────────────────── - - def plot_background(self, method: str, pixels=None, n_sample: int = 5): - """ - Three-panel diagnostic figure for a single method. - - Panel 1: raw flux + background estimate for sampled pixels. - Panel 2: astrophysical residual (flux − background). - Panel 3: blend-weight alpha (savgol) or mean absolute correction. - """ - if method not in self._backgrounds: - raise KeyError(f"Fit '{method}' first.") - - bkg = self._backgrounds[method] - astro = self._astro[method] - t = self.time - - # --- choose display pixels (mix source + background) ---------------- - if pixels is None: - src_c = np.argwhere(self._source_mask & ~self._strap_mask) - bkg_c = np.argwhere(self._bkg_mask) - rng = np.random.default_rng(42) - n_src = min(n_sample // 2 + 1, len(src_c)) - n_bk = min(n_sample - n_src, len(bkg_c)) - pix = [] - if n_src > 0: - pix.append(src_c[rng.choice(len(src_c), n_src, replace=False)]) - if n_bk > 0: - pix.append(bkg_c[rng.choice(len(bkg_c), n_bk, replace=False)]) - pixels = np.vstack(pix) if pix else np.array([[0, 0]]) - - gap_idx = np.where(np.diff(t) > 0.5)[0] - - def _ng(arr): - a = arr.copy().astype(float) - if len(gap_idx): - a[gap_idx] = np.nan - return a - - fig, axes = plt.subplots( - 3, 1, - figsize=(1.5 * fig_width, 3.5 * fig_width), - sharex=True, - ) - - ax = axes[0] - for k, (yi, xi) in enumerate(pixels): - c = f'C{k}' - ax.plot(t, _ng(self.flux[:, yi, xi]), - '.', color=c, ms=1.5, alpha=0.3) - ax.plot(t, _ng(bkg[:, yi, xi]), - '-', color=c, lw=1.0, label=f'bkg ({yi},{xi})') - ax.set_ylabel('Flux (e⁻/s)', fontsize=10) - ax.set_title(f'{method} — raw (dots) and background (lines)', fontsize=10) - ax.legend(fontsize=7, ncol=2) - - ax = axes[1] - for k, (yi, xi) in enumerate(pixels): - ax.plot(t, _ng(astro[:, yi, xi]), - '.', color=f'C{k}', ms=1.5, alpha=0.5, - label=f'astro ({yi},{xi})') - ax.axhline(0, color='k', lw=0.8, ls='--') - ax.set_ylabel('Residual (e⁻/s)', fontsize=10) - ax.legend(fontsize=7, ncol=2) - - ax = axes[2] - if method == 'savgol': - alpha_all = np.full(self._T, np.nan) - for start, end in self._segment_indices(): - n = end - start - if n < 5: - continue - av = np.nanmean(self.flux[start:end][:, self._bkg_mask], axis=1) - alpha_all[start:end] = self._gradient_blend_weights(av, n) - ax.plot(t, _ng(alpha_all), lw=1, color='C2', label='α (1=wide, 0=narrow)') - ax.set_ylim(-0.05, 1.05) - ax.set_ylabel('Blend weight α', fontsize=10) - else: - delta = np.nanmean(np.abs(bkg - self.flux), axis=(1, 2)) - ax.plot(t, _ng(delta), lw=1, color='C3', - label='Mean |background correction|') - ax.set_ylabel('Mean |correction| (e⁻/s)', fontsize=10) - ax.legend(fontsize=8) - ax.set_xlabel('Time (MJD)', fontsize=10) - - plt.tight_layout() - plt.show() - - def plot_comparison(self, example_pixel=None): - """ - Two-panel comparison of all fitted methods. - - Panel 1: bar chart of RMS scatter per method. - Panel 2: background estimates for an example source pixel. - """ - if not self._backgrounds: - raise RuntimeError("No methods fitted yet. Call fit() first.") - - sc = self.compare() - meths = list(sc) - - if example_pixel is None: - src_c = np.argwhere(self._source_mask & ~self._strap_mask) - if len(src_c) == 0: - src_c = np.argwhere(~self._strap_mask) - yi, xi = src_c[np.random.default_rng(0).integers(len(src_c))] - else: - yi, xi = example_pixel - - t = self.time - gap_idx = np.where(np.diff(t) > 0.5)[0] - - def _ng(arr): - a = arr.copy().astype(float) - if len(gap_idx): - a[gap_idx] = np.nan - return a - - fig, axes = plt.subplots( - 1, 2, - figsize=(3.0 * fig_width, 1.5 * fig_width), - ) - - ax = axes[0] - vals = [sc[m] if isinstance(sc[m], float) else 0 for m in meths] - colors = [f'C{i}' for i in range(len(meths))] - ax.bar(meths, vals, color=colors) - ax.set_ylabel('RMS scatter (e⁻/s)', fontsize=10) - ax.set_title('Background-pixel residual RMS\n(lower = better)', fontsize=10) - ax.tick_params(axis='x', rotation=30) - - ax = axes[1] - ax.plot(t, _ng(self.flux[:, yi, xi]), - '.k', ms=1.5, alpha=0.3, label='Raw flux') - for m, col in zip(meths, colors): - ax.plot(t, _ng(self._backgrounds[m][:, yi, xi]), - lw=1.2, color=col, label=m) - ax.set_xlabel('Time (MJD)', fontsize=10) - ax.set_ylabel('Flux (e⁻/s)', fontsize=10) - ax.set_title(f'Background estimates — pixel ({yi},{xi})', fontsize=10) - ax.legend(fontsize=7) - - plt.tight_layout() - plt.show() - - def plot_mask(self): - """Show the mask with source, strap, unlabelled, and background pixels.""" - display = np.zeros((self._X, self._Y), dtype=int) - display[self._bkg_mask] = 0 # background - display[self._strap_mask] = 1 # strap - display[self._source_mask] = 2 # labelled source - display[self._unlabelled_mask & ~self._source_mask] = 3 # unlabelled - - cmap = matplotlib.colors.ListedColormap( - ['#e0e0e0', '#f9a825', '#1565c0', '#c62828'] - ) - bounds = [-0.5, 0.5, 1.5, 2.5, 3.5] - norm = matplotlib.colors.BoundaryNorm(bounds, cmap.N) - - fig, ax = plt.subplots(figsize=(fig_width, fig_width)) - im = ax.imshow(display, origin='lower', cmap=cmap, norm=norm, - interpolation='nearest') - cbar = fig.colorbar(im, ax=ax, ticks=[0, 1, 2, 3]) - cbar.ax.set_yticklabels( - ['Background', 'Strap', 'Source (mask)', 'Source (detected)'], - fontsize=8, - ) - ax.set_title('Pixel classification mask', fontsize=10) - plt.tight_layout() - plt.show() - - # ── unlabelled-source detection ─────────────────────────────────────────── - - def _detect_unlabelled_sources(self, ell_max=0.5, thresh=3.0) -> np.ndarray: - """ - Identify pixels that behave like astrophysical sources but are not - flagged in the provided mask. - - Uses SEP (Source Extractor Python) to detect sources in the temporal - median image. Only sources with ellipticity < ell_max are kept. - Their pixel footprints are marked using a circular aperture of - radius = 2.5 * half-light radius (semi-major axis from SEP). - - Parameters - ---------- - ell_max : float - Maximum ellipticity (1 - b/a) for a source to be flagged. - Default 0.5. - thresh : float - SEP detection threshold in units of background sigma. Default 3.0. - - Returns - ------- - unlabelled : ndarray bool (X, Y) - True for newly detected source pixels. - """ - import sep - med_img = np.nanmedian(self.flux, axis=0).astype(np.float64) - # SEP requires C-contiguous float64 - med_img = np.ascontiguousarray(med_img) - # Estimate background from non-masked pixels - try: - bkg = sep.Background(med_img, mask=~self._bkg_mask.astype(np.uint8)) - data_sub = med_img - bkg.back() - noise = bkg.globalrms - objects = sep.extract(data_sub, thresh, err=noise) - except Exception: - return np.zeros((self._X, self._Y), dtype=bool) - - unlabelled = np.zeros((self._X, self._Y), dtype=bool) - ys_g, xs_g = np.mgrid[0:self._X, 0:self._Y] - for obj in objects: - if obj['a'] < 1e-3: - continue - ell = 1.0 - obj['b'] / obj['a'] - if ell > ell_max: - continue - # circular footprint radius = 2.5 * half-light radius (a is semi-major) - r = max(2.5 * obj['a'], 2.0) - dist2 = (ys_g - obj['y'])**2 + (xs_g - obj['x'])**2 - pix = dist2 <= r**2 - # Only flag pixels not already labelled as sources - unlabelled |= pix & ~self._source_mask & ~self._strap_mask - return unlabelled - - # ── utilities ───────────────────────────────────────────────────────────── - - def _segment_indices(self, gap_thresh: float = 0.5): - """List of (start, end) index pairs for contiguous time segments.""" - breaks = np.where(np.diff(self.time) > gap_thresh)[0] + 1 - starts = np.concatenate([[0], breaks]) - ends = np.concatenate([breaks, [self._T]]) - return list(zip(starts.tolist(), ends.tolist())) - - def _gradient_blend_weights(self, av: np.ndarray, n: int) -> np.ndarray: - """ - Per-frame blend weight alpha ∈ [0, 1] based on local background gradient. - alpha = 1 → stable → use wide SavGol - alpha = 0 → variable → use narrow SavGol - """ - rw = _make_odd(max(min(n // 32, 51), 5)) - rw = min(rw, n if n % 2 == 1 else n - 1) - av_rough = savgol_filter(av, rw, 1) - grad = np.abs(np.gradient(av_rough)) - gw = max(min(n // 32, 25), 3) - grad_smooth = np.convolve(grad, np.ones(gw) / gw, mode='same') - med_grad = float(np.nanmedian(grad_smooth)) - if med_grad < 1e-10: - return np.ones(n) - rate_norm = grad_smooth / med_grad - return np.clip(1.0 / np.maximum(rate_norm, 1.0), 0.0, 1.0) - - def _rpca_ialm(self, M, lam, max_iter=500, tol=1e-7): - """ - Inexact Augmented Lagrange Multiplier for Robust PCA. - Decomposes M = L + S (low-rank L, sparse S). - Reference: Lin, Chen, Ma (2010). - """ - m, n = M.shape - mu = m * n / (4.0 * (np.sum(np.abs(M)) + 1e-12)) - mu_bar = mu * 1e7 - rho = 1.5 - norm_M = np.linalg.norm(M, 'fro') + 1e-12 - - L = np.zeros_like(M) - S = np.zeros_like(M) - Y = M / max(np.linalg.norm(M, 2), np.linalg.norm(M, np.inf) / lam) - - for _ in range(max_iter): - # Singular value thresholding for L - U, sv, Vt = np.linalg.svd(M - S + Y / mu, full_matrices=False) - L = (U * np.maximum(sv - 1.0 / mu, 0.0)) @ Vt - - # Element-wise soft thresholding for S - tmp = M - L + Y / mu - S = np.sign(tmp) * np.maximum(np.abs(tmp) - lam / mu, 0.0) - - R = M - L - S - Y += mu * R - mu = min(mu * rho, mu_bar) - - if np.linalg.norm(R, 'fro') / norm_M < tol: - break - - return L, S - - # ── negative flux floor ─────────────────────────────────────────────────── - - def floor_negative_flux(self, noise_floor=0.5, max_iter=3): - """ - Recompute physically impossible negative flux values via inpainting. - - For each frame, pixels where flux < -noise_floor * per-pixel_noise are - treated as bad and filled using biharmonic inpainting from their - neighbours (same approach as tessreduce). The process iterates up to - `max_iter` times per frame until no pixels violate the condition, or - until no further improvement is possible. Only valid for raw - (non-differenced) images. - - Parameters - ---------- - noise_floor : float - Multiplier on the per-pixel noise estimate. Default 0.5. - max_iter : int - Maximum inpainting iterations per frame. Default 3. - """ - - from skimage.restoration import inpaint as sk_inpaint - - med = np.nanmedian(self.flux, axis=0) - mad = np.nanmedian(np.abs(self.flux - med[np.newaxis, :, :]), axis=0) - noise = 1.4826 * mad # (X, Y) - threshold = -noise_floor * noise # (X, Y) — always <= 0 - - yx_all = np.array([[y, x] for y in range(self._X) for x in range(self._Y)]) - - for t in range(self._T): - frame = self.flux[t].copy() - for _ in range(max_iter): - bad = frame < threshold - if not bad.any(): - break - good = ~bad - good_yx = np.argwhere(good) - good_vals = frame[good] - # Fast spatial interpolation from good pixels - filled_flat = griddata(good_yx, good_vals, yx_all, - method='linear', fill_value=np.nan) - filled = filled_flat.reshape(self._X, self._Y) - # Nearest-neighbour fallback for any remaining NaNs - still_nan = bad & ~np.isfinite(filled) - if still_nan.any(): - filled_nn = griddata(good_yx, good_vals, yx_all[still_nan.ravel()], - method='nearest') - filled[still_nan] = filled_nn - # For persistent edge cases use biharmonic inpainting - still_bad = filled < threshold - if still_bad.any(): - frame_masked = frame.copy() - frame_masked[still_bad] = np.nan - filled_bh = sk_inpaint.inpaint_biharmonic( - frame_masked, still_bad.astype(bool) - ) - filled[still_bad] = filled_bh[still_bad] - frame[bad] = filled[bad] - self.flux[t] = frame - - return self.flux - - # ── Method 0: Physical vectors (Earth/Moon angles) ──────────────────────── - - def _fit_vectors(self, sector, camera, ccd, gap_thresh=0.5): - """ - Background model driven by physical spacecraft vectors (Earth/Moon angles). - - Uses the `tessvectors` package to retrieve Earth angle, Moon angle from - boresight as a function of time. Fits a linear harmonic model per pixel - using background pixels, then predicts background for all pixels. - - Parameters - ---------- - sector : int - camera : int - ccd : int - """ - try: - import tessvectors - except ImportError: - raise ImportError( - "tessvectors is required for the 'vectors' method. " - "See https://github.com/tessgi/tessvectors" - ) - - # Get vectors for this sector/camera/ccd - # tessvectors returns a table with columns including 'time', 'EarthAngle', 'MoonAngle' - vec_table = tessvectors.get_vectors(sector, camera, ccd) - vec_time = np.array(vec_table['time']) # MJD - - # Interpolate vectors to our time grid - from scipy.interpolate import interp1d - - def _interp_vec(col_name): - v = np.array(vec_table[col_name], dtype=float) - f = interp1d(vec_time, v, bounds_error=False, fill_value='extrapolate') - return f(self.time) - - # Try common column names used by tessvectors - earth_angle = _interp_vec('EarthAngle') if 'EarthAngle' in vec_table.colnames else None - moon_angle = _interp_vec('MoonAngle') if 'MoonAngle' in vec_table.colnames else None - - # Build design matrix: [1, sin(e), cos(e), sin(m), cos(m)] - cols = [np.ones(self._T)] - if earth_angle is not None: - cols += [np.sin(np.radians(earth_angle)), np.cos(np.radians(earth_angle))] - if moon_angle is not None: - cols += [np.sin(np.radians(moon_angle)), np.cos(np.radians(moon_angle))] - A = np.column_stack(cols) # (T, n_features) - - bkg = deepcopy(self.flux) - bkg_yx = np.argwhere(self._bkg_mask) - - if len(bkg_yx) < 3: - return bkg - - # Fit all pixels simultaneously: solve A @ C = F (T, n_feat) @ (n_feat, X*Y) = (T, X*Y) - flux_2d = self.flux.reshape(self._T, -1) # (T, X*Y) - nan_cols = ~np.all(np.isfinite(flux_2d), axis=0) - flux_clean = flux_2d.copy() - flux_clean[:, nan_cols] = 0.0 - - try: - C, _, _, _ = np.linalg.lstsq(A, flux_clean, rcond=None) # (n_feat, X*Y) - bkg_2d = A @ C # (T, X*Y) — purely additive prediction - except np.linalg.LinAlgError: - return bkg - - bkg_2d[:, nan_cols] = np.nan - bkg = bkg_2d.reshape(self._T, self._X, self._Y) - return bkg - - # ── Method 1: Adaptive Savitzky-Golay ──────────────────────────────────── - - def _fit_savgol(self, gap_thresh: float = 0.5) -> np.ndarray: - """ - Per-pixel adaptive Savitzky-Golay background. - - Background pixels are smoothed temporally. Source and strap pixels - receive a background estimate by spatial linear interpolation from - the surrounding background pixel values at each frame. This prevents - source flux from contaminating the background model. - - For each time segment: - - Compute the gradient of the spatial-mean background (background pixels only). - - Derive a blend weight alpha per frame. - - Apply: bkg = alpha * savgol(wide) + (1-alpha) * savgol(narrow) - on background pixels only, then interpolate spatially to all pixels. - """ - - - bkg = np.full_like(self.flux, np.nan) - segs = self._segment_indices(gap_thresh) - - bkg_yx = np.argwhere(self._bkg_mask) # (N_bkg, 2) - all_yx = np.array([[y, x] for y in range(self._X) for x in range(self._Y)]) - - for start, end in segs: - n = end - start - if n < 5: - continue - - seg = self.flux[start:end] # (n, X, Y) - av = np.nanmean(seg[:, self._bkg_mask], axis=1) # (n,) - alpha = self._gradient_blend_weights(av, n) - - w_wide = _make_odd(max(n // 4, 5)) - w_narrow = _make_odd(max(n // 32, 5)) - w_wide = min(w_wide, n if n % 2 == 1 else n - 1) - w_narrow = min(w_narrow, n if n % 2 == 1 else n - 1) - - # Smooth only background pixel time series - bkg_ts = seg[:, self._bkg_mask] # (n, N_bkg) - bkg_ts_filled = _nan_interp_axis0(bkg_ts[:, :, np.newaxis])[:, :, 0] - sv_wide = savgol_filter(bkg_ts_filled, w_wide, 1, axis=0) - sv_narrow = savgol_filter(bkg_ts_filled, w_narrow, 1, axis=0) - - a = alpha[:, np.newaxis] - bkg_ts_smooth = a * sv_wide + (1.0 - a) * sv_narrow # (n, N_bkg) - - # Spatial interpolation per frame to fill source/strap pixels - result = np.empty((n, self._X, self._Y), dtype=float) - for ti in range(n): - vals = bkg_ts_smooth[ti] # (N_bkg,) - frame_bkg = griddata( - bkg_yx, vals, all_yx, method='linear', fill_value=np.nan, - ) - # Nearest-neighbour fill for any remaining NaNs at edges - nan_mask = ~np.isfinite(frame_bkg) - if nan_mask.any(): - frame_bkg[nan_mask] = griddata( - bkg_yx, vals, all_yx[nan_mask], method='nearest', - ) - result[ti] = frame_bkg.reshape(self._X, self._Y) - - result[~np.isfinite(seg)] = np.nan - bkg[start:end] = result - - return bkg - - # ── Method 2: Gaussian Process ──────────────────────────────────────────── - - def _fit_gp( - self, - gap_thresh: float = 0.5, - l_fraction: float = 0.15, - ) -> np.ndarray: - """ - Per-pixel Gaussian Process (RBF kernel), batch-solved over all pixels. - - The covariance matrix K depends only on the time grid (shared by all - pixels), so K^{-1} is computed once per segment and applied to all - X*Y pixels simultaneously via a single linear solve. - - l = l_fraction * n (in frame units). - noise_var estimated from high-frequency residuals of the spatial mean. - """ - bkg = deepcopy(self.flux) - segs = self._segment_indices(gap_thresh) - frames = np.arange(self._T, dtype=float) - - for start, end in segs: - n = end - start - if n < 5: - continue - - seg = self.flux[start:end] # (n, X, Y) - f_idx = frames[start:end] # (n,) frame indices - - av = np.nanmean(seg[:, self._bkg_mask], axis=1) - l = l_fraction * n - - # Noise from HF residuals - rw = _make_odd(max(min(n // 16, 51), 5)) - rw = min(rw, n if n % 2 == 1 else n - 1) - av_s = savgol_filter(av, rw, 1) - noise_var = max(float(np.nanvar(av - av_s)), 1e-10) - sig_var = max(float(np.nanvar(av)), noise_var) - - # RBF kernel - di = f_idx[:, None] - f_idx[None, :] # (n, n) - K_sig = sig_var * np.exp(-0.5 * (di / l) ** 2) - K = K_sig + noise_var * np.eye(n) - - # Solve only for background pixels, then interpolate spatially - - - bkg_yx = np.argwhere(self._bkg_mask) - all_yx = np.array([[y, x] for y in range(self._X) for x in range(self._Y)]) - - bkg_ts = seg[:, self._bkg_mask] # (n, N_bkg) - nan_cols = ~np.all(np.isfinite(bkg_ts), axis=0) - bkg_clean = bkg_ts.copy() - bkg_clean[:, nan_cols] = 0.0 - - try: - coeff = la_solve(K, bkg_clean) # (n, N_bkg) - bkg_smooth = K_sig @ coeff # (n, N_bkg) - except np.linalg.LinAlgError: - continue - - bkg_smooth[:, nan_cols] = np.nan - - # Spatial interpolation per frame - result = np.empty((n, self._X, self._Y), dtype=float) - for ti in range(n): - vals = bkg_smooth[ti] - ok = np.isfinite(vals) - if ok.sum() < 3: - result[ti] = np.nan - continue - frame_bkg = griddata(bkg_yx[ok], vals[ok], all_yx, - method='linear', fill_value=np.nan) - nan_mask = ~np.isfinite(frame_bkg) - if nan_mask.any(): - frame_bkg[nan_mask] = griddata( - bkg_yx[ok], vals[ok], all_yx[nan_mask], method='nearest', - ) - result[ti] = frame_bkg.reshape(self._X, self._Y) - - result[~np.isfinite(seg)] = np.nan - bkg[start:end] = result - - return bkg - - # ── Method 3: Local PCA (PLD-style) ─────────────────────────────────────── - - def _fit_local_pca( - self, - radius: float = 5.0, - n_components: int = 3, - gap_thresh: float = 0.5, - ) -> np.ndarray: - """ - Pixel-level decorrelation using nearby background pixels. - - Source pixels: - 1. Find background pixels within `radius` (expand if needed). - 2. Normalise their time series; compute SVD → k temporal basis vectors. - 3. Regress source pixel time series against basis + constant. - 4. Fitted systematic = background estimate. - - Background pixels: - Per-pixel SavGol with window n//4. - - Robust to spatial non-coherence because only LOCAL neighbours are used. - """ - bkg = deepcopy(self.flux) - segs = self._segment_indices(gap_thresh) - bkg_yx = np.argwhere(self._bkg_mask) # (N_bkg, 2) - src_yx = np.argwhere(self._source_mask | self._unlabelled_mask) # (N_src, 2) - - # ── Background pixels: per-pixel SavGol ────────────────────────────── - for (yi, xi) in bkg_yx: - ts = self.flux[:, yi, xi].copy() - for start, end in segs: - n = end - start - if n < 5: - continue - w = _make_odd(max(n // 4, 5)) - w = min(w, n if n % 2 == 1 else n - 1) - seg_ts = ts[start:end] - good = np.isfinite(seg_ts) - if good.sum() < 3: - continue - filled = np.interp(np.arange(n), np.where(good)[0], seg_ts[good]) - ts[start:end] = savgol_filter(filled, w, 1) - bkg[:, yi, xi] = ts - - # ── Source pixels: local PCA ────────────────────────────────────────── - if len(bkg_yx) < 2 or len(src_yx) == 0: - return bkg - - tree = cKDTree(bkg_yx) - - for (ys, xs) in src_yx: - # Expand radius until enough neighbours - r = radius - while True: - idx = tree.query_ball_point([ys, xs], r) - if len(idx) >= n_components + 1: - break - r *= 1.5 - if r > max(self._X, self._Y) * 2: - break - if len(idx) < 2: - continue - - nbrs = bkg_yx[idx] # (M, 2) - - # Process each segment - for start, end in segs: - n = end - start - if n < 5: - continue - - # Local background time series matrix (M, n) - B = self.flux[start:end, nbrs[:, 0], nbrs[:, 1]].T.astype(float) - - # Normalise each reference pixel - mu_B = np.nanmean(B, axis=1, keepdims=True) - std_B = np.nanstd(B, axis=1, keepdims=True) - std_B[std_B < 1e-10] = 1.0 - B_norm = (B - mu_B) / std_B - - # Drop mostly-NaN rows - valid = np.sum(np.isfinite(B_norm), axis=1) > n // 2 - if valid.sum() < 1: - continue - B_norm = np.nan_to_num(B_norm[valid], nan=0.0) - - k_eff = min(n_components, B_norm.shape[0]) - try: - _, _, Vt = np.linalg.svd(B_norm, full_matrices=False) - except np.linalg.LinAlgError: - continue - basis = Vt[:k_eff].T # (n, k_eff) - - flux_pix = self.flux[start:end, ys, xs].copy() - good = np.isfinite(flux_pix) - if good.sum() < k_eff + 2: - continue - - A = np.column_stack([basis[good], np.ones(good.sum())]) - c, _, _, _ = np.linalg.lstsq(A, flux_pix[good], rcond=None) - - A_full = np.column_stack([basis, np.ones(n)]) - bkg[start:end, ys, xs] = A_full @ c - - return bkg - - # ── Method 4: Robust PCA ────────────────────────────────────────────────── - - def _fit_rpca( - self, - lam: float = None, - max_iter: int = 500, - tol: float = 1e-7, - ) -> np.ndarray: - """ - Robust PCA via Inexact ALM (Principal Component Pursuit). - - Decomposes flux matrix M = L + S where: - L low-rank → background / scattered light - S sparse → astrophysical transients - - Does not assume spatial coherence. L is low-rank globally, driven - by the small number of physical processes causing the background. - """ - T, X, Y = self._T, self._X, self._Y - M_full = self.flux.reshape(T, X * Y).T # (X*Y, T) - - # normalise only; rescaled additively after decomposition - row_means = np.nanmean(M_full, axis=1, keepdims=True) - row_means[row_means == 0] = 1.0 - M_norm = M_full / row_means - nan_mask = ~np.isfinite(M_norm) - M_clean = np.where(nan_mask, 0.0, M_norm) - - lam_val = lam if lam is not None else 1.0 / np.sqrt(max(X * Y, T)) - L_norm, _ = self._rpca_ialm(M_clean, lam_val, max_iter, tol) - - L = (L_norm * row_means).T.reshape(T, X, Y) - L[~np.isfinite(self.flux)] = np.nan - return L - - # ── Method 5: NMF ──────────────────────────────────────────────────────── - - def _fit_nmf( - self, - n_components: int = 5, - max_iter: int = 500, - ) -> np.ndarray: - """ - Non-negative Matrix Factorization background. - - NMF is physically motivated: flux and background are non-negative. - Fit the temporal basis W only on background pixels, then apply - to all pixels via non-negative least squares. - - Requires scikit-learn. - """ - if not _HAS_SKLEARN: - raise ImportError( - "scikit-learn is required for the 'nmf' method. " - "Install with: pip install scikit-learn" - ) - T, X, Y = self._T, self._X, self._Y - flux_flat = self.flux.reshape(T, X * Y) - - offset = max(0.0, -float(np.nanmin(flux_flat))) + 1.0 - flux_pos = flux_flat + offset - - bkg_idx = np.where(self._bkg_mask.ravel())[0] - flux_bkg = flux_pos[:, bkg_idx] - - # Handle NaN - col_med = np.nanmedian(flux_bkg, axis=0) - nan_loc = ~np.isfinite(flux_bkg) - flux_bkg_clean = flux_bkg.copy() - flux_bkg_clean[nan_loc] = np.take(col_med, np.where(nan_loc)[1]) - - k = min(n_components, min(flux_bkg_clean.shape) - 1) - nmf = _NMF(n_components=k, init='nndsvd', max_iter=max_iter, random_state=0) - W = nmf.fit_transform(flux_bkg_clean) # (T, k) - - bkg_flat = np.zeros((T, X * Y)) - for px in range(X * Y): - ts = flux_pos[:, px] - ok = np.isfinite(ts) - if ok.sum() < k: - bkg_flat[:, px] = np.nan - continue - c, _ = nnls(W[ok], ts[ok]) - bkg_flat[:, px] = W @ c - - bkg_flat -= offset - bkg_flat[~np.isfinite(flux_flat)] = np.nan - return bkg_flat.reshape(T, X, Y) - - # ── Method 6: Convolutional Autoencoder ─────────────────────────────────── - - def _fit_autoenc( - self, - bottleneck: int = 32, - n_epochs: int = 300, - lr: float = 5e-4, - batch_size: int = 256, - noise_scale: float = 0.05, - n_neighbors: int = 16, - ) -> np.ndarray: - """ - 1-D temporal convolutional autoencoder trained on background pixels. - - Architecture: multi-scale Conv1d encoder → bottleneck → ConvTranspose1d decoder. - - Training data: background pixel time series (globally normalised, denoising). - Inference: - - Background pixels: use their own reconstruction. - - Source/strap pixels: replace latent code with IDW-interpolated code from - the n_neighbors nearest background pixels, then decode. This prevents - source-flux contamination of the background estimate. - - Normalisation: global background statistics (median/MAD across all background - pixels at each time step) so that per-pixel mean is not inflated by sources. - - Requires PyTorch. - """ - try: - import torch - import torch.nn as nn - except ImportError: - raise ImportError( - "PyTorch is required for the 'autoenc' method. " - "Install with: pip install torch" - ) - - T, X, Y = self._T, self._X, self._Y - bkg_flat_mask = self._bkg_mask.ravel() # (X*Y,) bool - - flux_2d = self.flux.reshape(T, X * Y).T # (X*Y, T) - bkg_rows = flux_2d[bkg_flat_mask] # (N_bkg, T) - - # Global normalisation: per-time-step median/MAD over background pixels - g_med = np.nanmedian(bkg_rows, axis=0, keepdims=True) # (1, T) - g_mad = np.nanmedian(np.abs(bkg_rows - g_med), axis=0, keepdims=True) * 1.4826 + 1e-8 - - # Per-pixel residual normalisation: remove local DC offset - def _normalise(rows): - z = (rows - g_med) / g_mad # global scale - dc = np.nanmean(z, axis=1, keepdims=True) - return np.nan_to_num(z - dc, nan=0.0) - - tr_norm = _normalise(bkg_rows) # (N_bkg, T) - dc_bkg = np.nanmean((bkg_rows - g_med) / g_mad, axis=1) # (N_bkg,) per-pixel offsets - - class _CAE(nn.Module): - def __init__(self, seq_len, bn): - super().__init__() - # multi-scale encoder: three parallel kernel sizes - self.enc_a = nn.Sequential(nn.Conv1d(1, 16, 7, padding=3), nn.GELU()) - self.enc_b = nn.Sequential(nn.Conv1d(1, 16, 15, padding=7), nn.GELU()) - self.enc_c = nn.Sequential(nn.Conv1d(1, 16, 31, padding=15), nn.GELU()) - self.merge = nn.Sequential( - nn.Conv1d(48, 32, 5, padding=2), nn.GELU(), - nn.Conv1d(32, 16, 3, padding=1), nn.GELU(), - nn.AdaptiveAvgPool1d(bn), - ) - self.dec = nn.Sequential( - nn.ConvTranspose1d(16, 32, 5, padding=2), nn.GELU(), - nn.ConvTranspose1d(32, 16, 7, padding=3), nn.GELU(), - nn.Conv1d(16, 1, 3, padding=1), - nn.Upsample(size=seq_len, mode='linear', align_corners=False), - ) - def encode(self, x): - return self.merge(torch.cat([self.enc_a(x), self.enc_b(x), self.enc_c(x)], dim=1)) - def decode(self, z): - return self.dec(z) - def forward(self, x): - return self.decode(self.encode(x)) - - device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') - model = _CAE(T, bottleneck).to(device) - opt = torch.optim.Adam(model.parameters(), lr=lr) - sched = torch.optim.lr_scheduler.CosineAnnealingLR(opt, T_max=n_epochs, eta_min=lr * 0.1) - crit = nn.HuberLoss(delta=1.0) - - X_tr = torch.tensor(tr_norm[:, None, :], dtype=torch.float32, device=device) - N_bkg = X_tr.shape[0] - model.train() - rng_t = torch.Generator(device=device) - for ep in range(n_epochs): - idx = torch.randperm(N_bkg, generator=rng_t, device=device) - ep_loss = 0.0 - for start in range(0, N_bkg, batch_size): - batch = X_tr[idx[start:start + batch_size]] - noisy = batch + noise_scale * torch.randn_like(batch) - opt.zero_grad() - loss = crit(model(noisy), batch) - loss.backward() - nn.utils.clip_grad_norm_(model.parameters(), 1.0) - opt.step() - ep_loss += loss.item() - sched.step() - - # ── Encode background pixels → get latent codes ──────────────────── - model.eval() - with torch.no_grad(): - latents_bkg = model.encode(X_tr).cpu().numpy() # (N_bkg, bn, 1or...) - # AdaptiveAvgPool → shape (N_bkg, 16, bottleneck) after merge; flatten last - latents_bkg = latents_bkg.reshape(N_bkg, -1) # (N_bkg, 16*bottleneck) - - # ── Spatial coordinates of background pixels ─────────────────────── - bkg_yx = np.argwhere(bkg_flat_mask.reshape(X, Y)) # (N_bkg, 2) - src_yx = np.argwhere(~bkg_flat_mask.reshape(X, Y)) # (N_src, 2) - - tree = cKDTree(bkg_yx) - dist, idx_nn = tree.query(src_yx, k=min(n_neighbors, N_bkg)) - dist = np.maximum(dist, 1e-6) - w = 1.0 / dist # (N_src, k) - w /= w.sum(axis=1, keepdims=True) - latents_src = np.stack([(w[i] @ latents_bkg[idx_nn[i]]) for i in range(len(src_yx))]) - - # DC offset for source pixels: IDW of neighbouring background pixel DCs - dc_src = np.stack([(w[i] @ dc_bkg[idx_nn[i]]) for i in range(len(src_yx))]) - - # ── Decode all pixels ────────────────────────────────────────────── - all_latents = np.zeros((X * Y, latents_bkg.shape[1]), dtype=np.float32) - all_latents[bkg_flat_mask] = latents_bkg - all_latents[~bkg_flat_mask] = latents_src.astype(np.float32) - - all_dc = np.zeros(X * Y, dtype=np.float64) - all_dc[bkg_flat_mask] = dc_bkg - all_dc[~bkg_flat_mask] = dc_src - - bn_size = bottleneck - ch = all_latents.shape[1] // bn_size - with torch.no_grad(): - z_t = torch.tensor( - all_latents.reshape(X * Y, ch, bn_size), dtype=torch.float32, device=device - ) - recon_norm = model.decode(z_t).squeeze(1).cpu().numpy() # (X*Y, T) - - # Add per-pixel DC back, then undo global normalisation - recon_z = recon_norm + all_dc[:, None] - bkg_flat = recon_z * g_mad + g_med # (X*Y, T) - bkg_flat[~np.isfinite(flux_2d)] = np.nan - return bkg_flat.T.reshape(T, X, Y) - - # ── Full pipeline ───────────────────────────────────────────────────────── - - def run_pipeline( - self, - bkg_method='savgol', - ref_frame=None, - sector=None, - camera=None, - ccd=None, - plot=False, - **bkg_kwargs, - ): - """ - Full two-stage background separation and image differencing pipeline. - - Stage 1 — background on raw data - --------------------------------- - 1. Floor negative flux values. - 2. Correct strap column QE (division only, straps only). - 3. Estimate background with `bkg_method`. - 4. Subtract background → stage-1 images. - 5. Calculate alignment shifts via SepAligner on stage-1 images. - - Stage 2 — differencing pipeline - -------------------------------- - 6. Start from QE-corrected original flux. - 7. Apply alignment shifts (ndimage shift, order=5). - 8. Subtract the chosen reference frame. - 9. Recompute background on difference images with a reduced mask: - - Strap columns (bit 4) are no longer masked. - - Source mask is morphologically eroded by ~50% in area. - 10. Subtract stage-2 background. - - Parameters - ---------- - bkg_method : str - Background method for both stages (default 'savgol'). - ref_frame : int or None - Index of the reference frame. If None, use the frame with the - lowest median background (good proxy for low scattered light). - sector, camera, ccd : int or None - Required only if bkg_method='vectors'. - plot : bool - If True, produce diagnostic plots at each stage. - - Returns - ------- - diff_cube : ndarray (T, X, Y) - Background-subtracted, aligned, differenced image cube. - shifts : ndarray (T, 2) - Alignment results from SepAligner in tessreduce convention - (shift[t] = [dy_apply, dx_apply]). - stage1_bkg : ndarray (T, X, Y) - Stage-1 background estimate. - stage2_bkg : ndarray (T, X, Y) - Stage-2 background estimate on difference images. - """ - from scipy.ndimage import shift as nd_shift - from scipy.ndimage import binary_erosion - from .sep_aligner import SepAligner - - # ── Stage 1 ──────────────────────────────────────────────────────────── - print('[TESSBackgroundSeparator] Stage 1: raw background estimation') - - # Floor unphysical negatives - self.floor_negative_flux() - - # QE-correct strap columns - flux_qe = self.correct_straps(plot=plot) # modifies self.flux in-place - - # Estimate background - extra = {} - if bkg_method == 'vectors': - if sector is None or camera is None or ccd is None: - raise ValueError("sector, camera, ccd required for vectors method") - extra = dict(sector=sector, camera=camera, ccd=ccd) - extra.update(bkg_kwargs) - - self.fit(method=bkg_method, **extra) - stage1_sub = flux_qe - self._backgrounds[bkg_method] - - # Choose reference frame: lowest median background if not specified - if ref_frame is None: - med_bkg = np.nanmedian(self._backgrounds[bkg_method], axis=(1, 2)) - ref_frame = int(np.argmin(med_bkg)) - print(f'[TESSBackgroundSeparator] Reference frame: {ref_frame} ' - f'(lowest background)') - - # ── Alignment ───────────────────────────────────────────────────────── - print('[TESSBackgroundSeparator] Calculating alignment shifts via SepAligner') - - # SepAligner requires a reference image and the full cube - ref_image_for_align = stage1_sub[ref_frame] - - # Source mask for SepAligner: combine labelled + detected sources (2D bool) - sep_source_mask = (self._source_mask | self._unlabelled_mask).astype(bool) - - aligner = SepAligner( - ref=ref_image_for_align, - flux=stage1_sub, - source_mask=sep_source_mask, - pixel_mask=self._strap_mask.astype(int), - ) - aligner.run() - - # aligner.shift is (T, 2) where shift[t] = [dy_apply, dx_apply] - # (tessreduce convention: apply as nd_shift(frame, [dy, dx])) - - # ── Stage 2: apply to QE-corrected original ──────────────────────────── - print('[TESSBackgroundSeparator] Stage 2: align, difference, background') - - # Apply shifts - flux_aligned = np.empty_like(flux_qe) - shifts_arr = aligner.shift # (T, 2): [dy_apply, dx_apply] - for i in range(self._T): - if shifts_arr is not None and np.all(np.isfinite(shifts_arr[i])): - dy_apply = float(shifts_arr[i, 0]) - dx_apply = float(shifts_arr[i, 1]) - flux_aligned[i] = nd_shift( - flux_qe[i].astype(np.float64), - [dy_apply, dx_apply], - order=5, - mode='nearest', - ) - else: - flux_aligned[i] = flux_qe[i] - - # Subtract reference frame (additive/subtractive only — no division) - ref_image = flux_aligned[ref_frame].copy() - diff_cube = flux_aligned - ref_image[np.newaxis, :, :] - - # Reduced mask for stage 2: - # - Ignore strap columns (bit 4 not masked) - # - Erode source mask to ~50% area (area ∝ r², so erode by 1 pixel ~reduces area) - # Erosion factor: iterate until area ≤ 50% of original - src_mask_orig = self._source_mask | self._unlabelled_mask - n_src_orig = src_mask_orig.sum() - eroded = src_mask_orig.copy() - for _ in range(20): - candidate = binary_erosion(eroded) - if candidate.sum() <= n_src_orig * 0.5: - eroded = candidate - break - eroded = candidate - - # Build stage-2 separator (no strap masking, reduced source mask) - # Encode eroded source mask as bit 1 (no bit 4 since we don't mask straps now) - stage2_mask = eroded.astype(int) # bit 1 = source only, no strap bit - - sep2 = TESSBackgroundSeparator( - diff_cube, - self.time, - stage2_mask, - expand_mask=False, # don't re-detect; differenced images are unusual - ) - # In differenced images negative values are permitted in source cores - # so we do NOT call floor_negative_flux here - - sep2.fit(method=bkg_method, **bkg_kwargs) - diff_cube_bkg_sub = diff_cube - sep2._backgrounds[bkg_method] - - if plot: - self._plot_pipeline_diagnostic( - flux_qe, stage1_sub, diff_cube, diff_cube_bkg_sub, - ref_frame, aligner, - ) - - return (diff_cube_bkg_sub, aligner.shift, - self._backgrounds[bkg_method], sep2._backgrounds[bkg_method]) - - def _plot_pipeline_diagnostic(self, flux_qe, stage1_sub, diff_raw, diff_sub, - ref_frame, aligner): - """Four-panel pipeline diagnostic.""" - t = self.time - gap_idx = np.where(np.diff(t) > 0.5)[0] - - def _ng(arr): - a = arr.copy().astype(float) - if len(gap_idx): - a[gap_idx] = np.nan - return a - - fig, axes = plt.subplots(4, 1, - figsize=(1.5 * fig_width, 4.5 * fig_width), - sharex=True) - - # Panel 1: QE-corrected flux spatial mean - axes[0].plot(t, _ng(np.nanmean(flux_qe, axis=(1, 2))), - '.k', ms=1.5, alpha=0.5, label='QE-corrected flux') - axes[0].set_ylabel('Mean flux (e⁻/s)', fontsize=9) - axes[0].set_title('Stage 1: QE-corrected input', fontsize=9) - - # Panel 2: Stage 1 background-subtracted - axes[1].plot(t, _ng(np.nanmean(stage1_sub, axis=(1, 2))), - '.', color='C0', ms=1.5, alpha=0.5, label='Stage 1 sub') - axes[1].axhline(0, color='k', lw=0.7, ls='--') - axes[1].set_ylabel('Mean flux (e⁻/s)', fontsize=9) - axes[1].set_title('Stage 1: after background subtraction', fontsize=9) - - # Panel 3: alignment shifts - if aligner.shift is not None: - # aligner.shift is (T, 2): col 0 = dy_apply, col 1 = dx_apply - # measured offsets (science - ref): dx = -shift[:,1], dy = -shift[:,0] - dxs = _ng(-aligner.shift[:, 1]) - dys = _ng(-aligner.shift[:, 0]) - axes[2].plot(t, dxs, lw=1, label='dx') - axes[2].plot(t, dys, lw=1, label='dy') - axes[2].set_ylabel('Shift (px)', fontsize=9) - axes[2].set_title('Alignment shifts', fontsize=9) - axes[2].legend(fontsize=8) - - # Panel 4: final differenced + stage-2 subtracted - axes[3].plot(t, _ng(np.nanmean(diff_raw, axis=(1, 2))), - '.', color='C1', ms=1.5, alpha=0.4, label='Diff raw') - axes[3].plot(t, _ng(np.nanmean(diff_sub, axis=(1, 2))), - lw=1, color='C2', label='Diff - bkg2') - axes[3].axhline(0, color='k', lw=0.7, ls='--') - axes[3].set_ylabel('Mean flux (e⁻/s)', fontsize=9) - axes[3].set_title('Stage 2: differenced - background', fontsize=9) - axes[3].legend(fontsize=8) - axes[3].set_xlabel('Time (MJD)', fontsize=9) - - plt.tight_layout() - plt.show() diff --git a/tessreduce/calibration_tools.py b/tessreduce/calibration_tools.py index 8b10faf..0beebc3 100755 --- a/tessreduce/calibration_tools.py +++ b/tessreduce/calibration_tools.py @@ -4,6 +4,7 @@ import astropy.table as at from collections import OrderedDict +import matplotlib.pyplot as plt import numpy as np from scipy import interpolate import astropy.table as at @@ -168,8 +169,6 @@ def Tonry_reduce(Data,plot=False,savename=None,system='ps1'): dat : dataframe Source catalog with added index of if source is on the stellar locus ''' - import matplotlib.pyplot as plt - data = deepcopy(Data) if system.lower() == 'ps1': tonry = np.loadtxt(os.path.join(dirname,'Tonry_splines.txt')) @@ -193,8 +192,8 @@ def Tonry_reduce(Data,plot=False,savename=None,system='ps1'): colours = Make_colours(dat.iloc[ind],tonry,compare,Extinction = res.x, Tonry = True,system=system) clip = Tonry_clip(colours,tonry) #clips += [clip] - dat.loc[ind,'locus'] = clip * 1 - dat2 = dat.loc[dat['locus'] > 0] + dat['locus'].iloc[ind] = clip + dat2 = dat.iloc[dat['locus'].values > 0] #print('Pass ' + str(i+1) + ': ' + str(res.x[0])) #clips[0][clips[0]] = clips[1] if plot: @@ -327,10 +326,8 @@ def Dist_tensor(X,Y,K,Colours,fitfilt='',Tensor=False,Plot = False): Returns ------- residual : float - residuals of distances from all points to the model locus. + residuals of distances from all points to the model locus. """ - import matplotlib.pyplot as plt - ob_x, ob_y, locus = Get_lcs(X,Y,K,Colours,fitfilt) ind = np.where((Colours['obs g-r'][0,:] <= .8) & (Colours['obs g-r'][0,:] >= 0.2))[0] diff --git a/tessreduce/calspec_mags.npy b/tessreduce/calspec_mags.npy new file mode 100755 index 0000000..17554bf Binary files /dev/null and b/tessreduce/calspec_mags.npy differ diff --git a/tessreduce/cat_mask.py b/tessreduce/cat_mask.py index a4050f9..e392658 100755 --- a/tessreduce/cat_mask.py +++ b/tessreduce/cat_mask.py @@ -25,7 +25,7 @@ def circle_app(rad): """ Makes a kinda circular aperture, probably not worth using. """ - mask = np.zeros((int(np.round(rad*2,0))+1,int(np.round(rad*2))+1)) + mask = np.zeros((int(rad*2+.5)+1,int(rad*2+.5)+1)) c = rad x,y =np.where(mask==0) dist = np.sqrt((x-c)**2 + (y-c)**2) @@ -42,8 +42,8 @@ def ps1_auto_mask(table,Image,scale=1): image = np.zeros_like(Image) x = table.x.values y = table.y.values - x = (np.round(x,0)).astype(int) - y = (np.round(y,0)).astype(int) + x = (x+.5).astype(int) + y = (y+.5).astype(int) m = table.mag.values ind = size_limit(x,y,image) x = x[ind]; y = y[ind]; m = m[ind] @@ -91,8 +91,8 @@ def gaia_auto_mask(table,Image,scale=1): image = np.zeros_like(Image) x = table.x.values y = table.y.values - x = (np.round(x,0)).astype(int) - y = (np.round(y,0)).astype(int) + x = (x+.5).astype(int) + y = (y+.5).astype(int) m = table.mag.values ind = size_limit(x,y,image) x = x[ind]; y = y[ind]; m = m[ind] @@ -105,15 +105,10 @@ def gaia_auto_mask(table,Image,scale=1): mags = [[18,17],[17,16],[16,15],[15,14],[14,13.5],[13.5,12],[12,10],[10,9],[9,8],[8,7]] size = (np.array([3,4,5,6,7,8,10,14,16,18])*scale).astype(int) for i, mag in enumerate(mags): - ind = (m > mag[1]) & (m <= mag[0]) - magim = np.zeros_like(image) - magim[y[ind],x[ind]] = 1. - if size[i] >0: - k = np.ones((size[i],size[i])) - conv = fftconvolve(magim, k,mode='same')#.astype(int) - masks[str(mag[0])] = (conv >.1) * 1. - else: - conv = magim + m = ((magim > mag[1]) & (magim <= mag[0])) * 1. + k = np.ones((size[i],size[i])) + conv = fftconvolve(m, k,mode='same')#.astype(int) + masks[str(mag[0])] = (conv >.1) * 1. masks['all'] = np.zeros_like(image,dtype=float) for key in masks: masks['all'] += masks[key] @@ -148,8 +143,8 @@ def Big_sat(table,Image,scale=1): sat = table.iloc[i] x = sat.x.values y = sat.y.values - x = (np.round(x,0)).astype(int) - y = (np.round(y,0)).astype(int) + x = (x+.5).astype(int) + y = (y+.5).astype(int) m = sat.mag.values ind = size_limit(x,y,image) @@ -160,17 +155,17 @@ def Big_sat(table,Image,scale=1): mag = m[i] mask = np.zeros_like(image,dtype=float) if (mag <= 7) & (mag > 5): - body = int(13 * scale) + body = int(13 * scale) length = int(20 * scale) - width = int(3 * scale) + width = int(3 * scale) if (mag <= 5) & (mag > 4): - body = 15 * scale + body = 15 * scale length = int(60 * scale) - width = int(5 * scale) + width = int(5 * scale) if (mag <= 4):# & (mag > 4): - body = int(22 * scale) + body = int(22 * scale) length = int(115 * scale) - width = int(7 * scale) + width = int(7 * scale) body = int(body) # no idea why this is needed, but it apparently is. kernel = np.zeros((body*2+1,body*2+1)) yy,xx = np.where(kernel == 0) @@ -200,103 +195,29 @@ def Big_sat(table,Image,scale=1): satmasks = np.array(satmasks) return satmasks -def detect_straps_empirical(flux_cube, size=4, min_snr=3.0): - """ - Detect strap columns empirically from a flux cube by identifying columns - whose flux correlates more strongly with the scattered light background - than their immediate neighbours. - - Straps have a multiplicative QE enhancement that scales with scattered - light, so during bright frames they are elevated relative to adjacent - non-strap columns. The detection works by: - 1. Forming a peak/quiet ratio profile (median over rows). - 2. Subtracting a running-median trend to remove broad spatial gradients. - 3. Flagging columns with residual ratio significantly above noise. - - Parameters - ---------- - flux_cube : ndarray (T, X, Y) - Raw flux cube. - size : int - Half-width in pixels to expand detected strap columns into a mask. - min_snr : float - Detection threshold in units of the residual profile's sigma. - - Returns - ------- - strap_cols : ndarray of int - Column indices identified as straps. - """ - from astropy.stats import sigma_clipped_stats - from scipy.ndimage import median_filter - - T, X, Y = flux_cube.shape - av = np.nanmedian(flux_cube, axis=(1, 2)) - - # Use the top and bottom 20% of frames for peak and quiet - n = max(int(T * 0.2), 5) - order = np.argsort(av) - quiet_idx = order[:n] - peak_idx = order[-n:] - - prof_peak = np.nanmedian(flux_cube[peak_idx], axis=(0, 1)) # (Y,) - prof_quiet = np.nanmedian(flux_cube[quiet_idx], axis=(0, 1)) # (Y,) - - with np.errstate(divide='ignore', invalid='ignore'): - ratio = prof_peak / prof_quiet - ratio = np.where(np.isfinite(ratio), ratio, 1.0) - - # Remove broad spatial trend with a wide median filter - trend = median_filter(ratio, size=max(21, Y // 10)) - residual = ratio - trend - - _, med_res, std_res = sigma_clipped_stats(residual) - thresh = med_res + min_snr * std_res - - # Expand each detected column by ±size//2 to match catalogue mask width - expanded = set() - for c in np.where(residual > thresh)[0]: - for offset in range(-(size // 2), size // 2 + 1): - expanded.add(int(c) + offset) - strap_cols = np.array(sorted(c for c in expanded if 0 <= c < Y), dtype=int) - return strap_cols - - -def Strap_mask(Image, col, size=4, flux_cube=None): +def Strap_mask(Image,col,size=4): """ Make a mask for the electrical straps on TESS CCDs. - Attempts catalogue-based strap positions first. If the TPF column offset - is zero (no WCS stored) or no catalogue straps fall inside the image, falls - back to empirical detection from the flux cube if one is provided. - Parameters ---------- + Image : ArrayLike Flux of a reference image. col : int - Reference index of TPF columns (tpf.column + col_offset). + Reference index of TPF columns. size : int, optional - Width of the strap mask in pixels. The default is 4. - flux_cube : ndarray (T, X, Y), optional - Full flux time series used for empirical strap detection fallback. + Width of the strap in pixels. The default is 4. """ - straps_csv = pd.read_csv(package_directory + 'tess_straps.csv')['Column'].values - strap_in_tpf = straps_csv - col + 44 - strap_in_tpf = strap_in_tpf[(strap_in_tpf > 0) & (strap_in_tpf < Image.shape[1])] - - # Fall back to empirical detection only when catalogue positions are - # unavailable (no straps land in the image after applying col_offset). - if len(strap_in_tpf) == 0 and flux_cube is not None: - strap_in_tpf = detect_straps_empirical(flux_cube, size=size) strap_mask = np.zeros_like(Image) - valid = strap_in_tpf[(strap_in_tpf >= 0) & (strap_in_tpf < Image.shape[1])] - strap_mask[:, valid] = 1 - big_strap = fftconvolve(strap_mask, np.ones((size, size)), mode='same') > .5 + straps = pd.read_csv(package_directory + 'tess_straps.csv')['Column'].values - col + 44 + strap_in_tpf = straps[((straps > 0) & (straps < Image.shape[1]))] + strap_mask[:,strap_in_tpf] = 1 + big_strap = fftconvolve(strap_mask,np.ones((size,size)),mode='same') > .5 return big_strap -def Cat_mask(tpf,catalogue_path=None,maglim=19,scale=1,strapsize=3,ref=None,sigma=3,col_offset=0,flux_cube=None): +def Cat_mask(tpf,catalogue_path=None,maglim=19,scale=1,strapsize=3,ref=None,sigma=3): """ Make a source mask from the PS1 and Gaia catalogs. @@ -329,24 +250,20 @@ def Cat_mask(tpf,catalogue_path=None,maglim=19,scale=1,strapsize=3,ref=None,sigm """ if catalogue_path is not None: - gaia = external_load_cat(catalogue_path,maglim) + gaia = external_load_cat(catalogue_path,maglim) coords = tpf.wcs.all_world2pix(gaia['ra'],gaia['dec'], 0) gaia['x'] = coords[0] gaia['y'] = coords[1] else: gp,gm = Get_Gaia(tpf,magnitude_limit=maglim) - gaia = pd.DataFrame(np.array([gp[:,0],gp[:,1],gm]).T,columns=['x','y','mag']) + gaia = pd.DataFrame(np.array([gp[:,0],gp[:,1],gm]).T,columns=['x','y','mag']) image = tpf.flux[10] image = strip_units(image) - NY, NX = image.shape - gaia = gaia[(gaia['x'] >= -1.5) & (gaia['x'] <= NX - 1 + 1.5) & - (gaia['y'] >= -1.5) & (gaia['y'] <= NY - 1 + 1.5)] - sat = Big_sat(gaia,image,scale) if ref is None: - mg = gaia_auto_mask(gaia,image,scale) + mg = gaia_auto_mask(gaia,image,scale) mask = (mg['all'] > 0).astype(int) * 1 # assign 1 bit else: mg = np.zeros_like(ref,dtype=int) @@ -359,8 +276,8 @@ def Cat_mask(tpf,catalogue_path=None,maglim=19,scale=1,strapsize=3,ref=None,sigm sat = (np.nansum(sat,axis=0) > 0).astype(int) * 2 # assign 2 bit - if strapsize > 0: - strap = Strap_mask(image,tpf.column+col_offset,strapsize,flux_cube=flux_cube).astype(int) * 4 # assign 4 bit + if strapsize > 0: + strap = Strap_mask(image,tpf.column,strapsize).astype(int) * 4 # assign 4 bit else: strap = np.zeros_like(image,dtype=int) diff --git a/tessreduce/catalog_tools.py b/tessreduce/catalog_tools.py index f0d3828..f8f145f 100755 --- a/tessreduce/catalog_tools.py +++ b/tessreduce/catalog_tools.py @@ -40,7 +40,7 @@ def Get_Catalogue(tpf, Catalog = 'gaia'): from astroquery.vizier import Vizier Vizier.ROW_LIMIT = -1 if Catalog == 'gaia': - catalog = "I/355/gaiadr3" + catalog = "I/345/gaia2" elif Catalog == 'dist': catalog = "I/355/gaiadr3" elif Catalog == 'ps1': @@ -75,10 +75,7 @@ def Get_Catalogue(tpf, Catalog = 'gaia'): def _get_skymapper(coord,rad): query = f'https://skymapper.anu.edu.au/sm-cone/public/query?RA={coord.ra.value}&DEC={coord.dec.value}&SR={np.round(rad.deg,3)}&RESPONSEFORMAT=CSV' - try: - sm = pd.read_csv(query) - except Exception: - return None + sm = pd.read_csv(query) if len(sm) > 0: keep = ['object_id','raj2000','dej2000','u_psf', 'e_u_psf', 'v_psf', 'e_v_psf','g_psf', 'e_g_psf','r_psf', @@ -122,9 +119,9 @@ def Get_Catalogue_External(ra,dec,size,Catalog = 'gaia'): from astroquery.vizier import Vizier Vizier.ROW_LIMIT = -1 if Catalog == 'gaia': - catalog = "I/355/gaiadr3" + catalog = "I/345/gaia2" elif Catalog == 'dist': - catalog = "I/355/gaiadr3" + catalog = "I/350/gaiaedr3" elif Catalog == 'ps1': catalog = "II/349/ps1" elif Catalog == 'skymapper': @@ -195,16 +192,14 @@ def Get_Gaia_External(ra,dec,size,wcsObj,magnitude_limit = 18, Offset = 10): source = result['Source'].values Gmag = result['Gmag'].values - RPmag = result['RPmag'].values #Jmag = result['Jmag'] - ind = (((coords[:,0] >= -10) & (coords[:,1] >= -10)) & + ind = (((coords[:,0] >= -10) & (coords[:,1] >= -10)) & ((coords[:,0] < (size + 10)) & (coords[:,1] < (size + 10)))) coords = coords[ind] radecs = radecs[ind] Gmag = Gmag[ind] - RPmag = RPmag[ind] source = source[ind] - Tmag = np.where(np.isfinite(RPmag) & (RPmag > 0), RPmag + 0.37, Gmag + 0.10 - 0.5) + Tmag = Gmag - 0.5 #Jmag = Jmag[ind] return radecs, Tmag, source @@ -238,14 +233,12 @@ def Get_Gaia(tpf, magnitude_limit = 18, Offset = 10): radecs = np.vstack([result['RA_ICRS'], result['DE_ICRS']]).T coords = tpf.wcs.all_world2pix(radecs, 0) ## TODO, is origin supposed to be zero or one? Gmag = result['Gmag'].values - RPmag = result['RPmag'].values #Jmag = result['Jmag'] - ind = (((coords[:,0] >= -10) & (coords[:,1] >= -10)) & + ind = (((coords[:,0] >= -10) & (coords[:,1] >= -10)) & ((coords[:,0] < (tpf.shape[2] + 10)) & (coords[:,1] < (tpf.shape[1] + 10)))) coords = coords[ind] Gmag = Gmag[ind] - RPmag = RPmag[ind] - Tmag = np.where(np.isfinite(RPmag) & (RPmag > 0), RPmag + 0.37, Gmag + 0.10 - 0.5) + Tmag = Gmag - 0.5 #Jmag = Jmag[ind] return coords, Tmag @@ -511,20 +504,14 @@ def external_save_cat(tpf,save_path,maglim): gp,gm, source = Get_Gaia_External(ra,dec,size,wcsObj,magnitude_limit=maglim) - gaia = pd.DataFrame(np.array([gp[:,0],gp[:,1],gm,source]).T,columns=['ra','dec','mag','Source']) + gaia = pd.DataFrame(np.array([gp[:,0],gp[:,1],gm,source]).T,columns=['ra','dec','mag','Source']) gaia.to_csv(f'{save_path}/local_gaia_cat.csv',index=False) def external_load_cat(path,maglim): gaia = pd.read_csv(path) - if 'RPmag' in gaia.columns and 'Gmag' in gaia.columns: - RPmag = gaia['RPmag'].values - Gmag = gaia['Gmag'].values - gaia['mag'] = np.where(np.isfinite(RPmag) & (RPmag > 0), RPmag + 0.37, Gmag + 0.10 - 0.5) - elif 'Gmag' in gaia.columns: - gaia['mag'] = gaia['Gmag'].values + 0.10 - 0.5 - gaia = gaia[gaia['mag']')[1:] - names = [] - for i in range(len(n)): - names - if '\n ' in n[i]: - names += [n[i].split('')[0]] - - names = list(set(names)) - self.cat_names = names - except: - print('No reported transients within 10arcsec of coordinates') - self.sn_name = None - self.cat_names = None - - def alias(self,catalog='ztf'): """ Cross refeerence the OSC to get selected catalog names @@ -186,13 +146,11 @@ def get_ztf_data(self): """ Gets the ztf light curve data. First checks that the transient name is defined """ - if self.ztf_name is None: - self._get_ztf_name() - # for name in self.cat_names: - # if 'ZTF' in name: - # ztf_name = name - if self.ztf_name is not None: - self.ztf = get_ztf(self.ztf_name) + if self.sn_name is None: + self.get_sn_name() + ztf_name = self.alias(catalog='ztf') + if ztf_name is not None: + self.ztf = get_ztf(ztf_name) return diff --git a/tessreduce/helpers.py b/tessreduce/helpers.py index 4e93ba5..2ee80e3 100644 --- a/tessreduce/helpers.py +++ b/tessreduce/helpers.py @@ -4,6 +4,7 @@ from copy import deepcopy import pandas as pd +import matplotlib.pyplot as plt import numpy as np from PIL import Image @@ -13,17 +14,15 @@ from scipy.ndimage import gaussian_filter from scipy.ndimage import convolve from scipy.ndimage import label -from scipy.ndimage import binary_dilation -from scipy.ndimage import laplace -from scipy.ndimage import median_filter -from scipy.ndimage import distance_transform_edt -from astropy.convolution import interpolate_replace_nans, Gaussian2DKernel -from joblib import Parallel, delayed from scipy.signal import savgol_filter from scipy.interpolate import interp1d from scipy.interpolate import griddata from scipy.optimize import minimize from scipy.signal import fftconvolve +from sklearn.cluster import OPTICS +from sklearn.preprocessing import PolynomialFeatures +from sklearn.linear_model import LinearRegression +from sklearn.pipeline import make_pipeline from skimage.restoration import inpaint @@ -54,22 +53,22 @@ def strip_units(data): """ - Removes the units off of data that was not in a NDarray, such as an astropy table. Returns an NDarray that has no units - - Parameters: - ---------- - data: ArrayLike - ArrayLike set of data that may have associated units that want to be removed. Should be able to return something sensible when .values is called. - - Returns: - ------- - data: ArrayLike - Same shape as input data, but will not have any units - """ + Removes the units off of data that was not in a NDarray, such as an astropy table. Returns an NDarray that has no units + + Parameters: + ---------- + data: ArrayLike + ArrayLike set of data that may have associated units that want to be removed. Should be able to return something sensible when .values is called. + + Returns: + ------- + data: ArrayLike + Same shape as input data, but will not have any units + """ if type(data) != np.ndarray: data = data.value - return deepcopy(data) + return data def sigma_mask(data,sigma=3): """ @@ -172,26 +171,7 @@ def parallel_bkg3(data,mask): estimate = inpaint.inpaint_biharmonic(data,mask) return estimate -def _background2d_frame(frame, box_size, filter_size, sc, estimator, mask=None): - from photutils.background import Background2D - try: - return Background2D(frame, box_size=box_size, filter_size=filter_size, - sigma_clip=sc, bkg_estimator=estimator, - mask=mask, fill_value=0.0, - exclude_percentile=50).background - except Exception: - return np.full_like(frame, np.nanmedian(frame)) - -def parallel_background2d(cube, box_size=5, filter_size=3, sigma=3, maxiters=5, n_jobs=-1, mask=None): - from photutils.background import MedianBackground - from astropy.stats import SigmaClip - sc = SigmaClip(sigma=sigma, maxiters=maxiters) - estimator = MedianBackground() - return np.array(Parallel(n_jobs=n_jobs)( - delayed(_background2d_frame)(frame, box_size, filter_size, sc, estimator, mask) - for frame in cube)) - -def Smooth_bkg(data, gauss_smooth=0, interpolate=False, extrapolate=True): +def Smooth_bkg(data, gauss_smooth=2, interpolate=False, extrapolate=True): """ Interpolate over the masked objects to derive a background estimate. @@ -231,21 +211,17 @@ def Smooth_bkg(data, gauss_smooth=0, interpolate=False, extrapolate=True): if extrapolate: estimate[np.isnan(estimate)] = nearest[np.isnan(estimate)] - if gauss_smooth > 0: - estimate = gaussian_filter(estimate,gauss_smooth) - + estimate = gaussian_filter(estimate,gauss_smooth) + #estimate = median_filter(estimate,5) else: - # try inpaint stuff + # try inpaint stuff mask = deepcopy(arr.mask) mask = mask.astype(bool) # end inpaint estimate = inpaint.inpaint_biharmonic(data,mask) #estimate = signal.fftconvolve(estimate,self.prf,mode='same') - if gauss_smooth > 0: - if (np.nanmedian(estimate) < 150) & (np.nanstd(estimate) < 3): - gauss_smooth = gauss_smooth * 4 - estimate = gaussian_filter(estimate,gauss_smooth) + estimate = gaussian_filter(estimate,gauss_smooth) else: estimate = np.zeros_like(data) * np.nan else: @@ -298,47 +274,19 @@ def Calculate_shifts(data,mx,my,finder): shifts[1,indo] = mx[indo] - x[ind] shifts[0,indo] = my[indo] - y[ind] else: - shifts[0,:] = np.nan - shifts[1,:] = np.nan + shifts[0,indo] = np.nan + shifts[1,indo] = np.nan return shifts -def image_sub(theta, image, ref):#, eimage, eref): +def image_sub(theta, image, ref): dx, dy = theta - s = shift(image,([dx,dy]),order=5, mode='nearest') + s = shift(image,([dx,dy]),order=5) #translation = np.float64([[1,0,dx],[0,1, dy]]) #s = cv2.warpAffine(image, translation, image.shape[::-1], flags=cv2.INTER_CUBIC,borderValue=0) - diff = (ref-s)**2#/(eimage + eref) - if image.shape[0] > 50: - return np.nansum(diff[10:-11,10:-11]) - else: - return np.nansum(diff[5:-6,5:-6]) - - -### TESTING CODE -#def c_shift_image(img, shift): -# return scipy.ndimage.shift(img, shift=shift, order=5, mode='nearest') # cubic interpolation -# -#def cost_function(shift, ref_img, moving_img): -# shifted = shift_image(moving_img, shift) -# diff = ref_img - shifted -# return np.sum(diff[2:-2,2:-2]**2) # Sum of Squared Differences (SSD) -# -#def align_subpixel(ref_img, moving_img, initial_shift=(0,0)): -# ref_img = ref_img.astype(np.float32) -# moving_img = moving_img.astype(np.float32) -# -# # Minimize SSD by shifting moving_img -# result = minimize(cost_function, initial_shift, args=(ref_img, moving_img), method='Powell') -# -# best_shift = result.x -# aligned_img = c_shift_image(moving_img, best_shift) -# -# print(f"Optimal shift (y, x): {best_shift}") -# return aligned_img, best_shift -### - - -def difference_shifts(image,ref):#,eimage,eref): + diff = (ref-s)**2 + return np.nansum(diff[5:-5,5:-5]) + +def difference_shifts(image,ref): """ Calculate the offsets of sources identified by photutils from a reference @@ -364,19 +312,16 @@ def difference_shifts(image,ref):#,eimage,eref): """ if np.nansum(abs(image)) > 0: x0= [0,0] - bds = [(-1.5,1.5),(-1.5,1.5)] - bds = [(-3,3),(-3,3)] - #res = minimize(image_sub,x0,args=(image,ref,eimage,eref),method = 'Powell',bounds= bds) + bds = [(-1,1),(-1,1)] res = minimize(image_sub,x0,args=(image,ref),method = 'Powell',bounds= bds) s = res.x - #a,s = align_subpixel(ref,image) else: s = np.zeros((2)) * np.nan if (s == np.ones((2))).any(): s = np.zeros((2)) * np.nan return s -def Smooth_motion(Centroids,tpf,skernel=25): +def Smooth_motion(Centroids,tpf): """ Calculate the smoothed centroid shift @@ -396,11 +341,6 @@ def Smooth_motion(Centroids,tpf,skernel=25): """ smoothed = np.zeros_like(Centroids) * np.nan - # skernel = int(len(tpf.flux) * 0.01) #simple way of making the smoothing window 10% of the duration - # skernel = skernel // 2 +1 - # #skernel = 25 - # if skernel < 25: - # skernel = 25 try: try: split = np.where(np.diff(tpf.time.mjd) > 0.5)[0][0] + 1 @@ -409,11 +349,11 @@ def Smooth_motion(Centroids,tpf,skernel=25): ind1 = np.where(ind1 != 0)[0] ind2 = np.nansum(tpf.flux[split:],axis=(1,2)) ind2 = np.where(ind2 != 0)[0] + split - smoothed[ind1,0] = savgol_filter(Centroids[ind1,0],skernel,3) - smoothed[ind2,0] = savgol_filter(Centroids[ind2,0],skernel,3) + smoothed[ind1,0] = savgol_filter(Centroids[ind1,0],25,3) + smoothed[ind2,0] = savgol_filter(Centroids[ind2,0],25,3) - smoothed[ind1,1] = savgol_filter(Centroids[ind1,1],skernel,3) - smoothed[ind2,1] = savgol_filter(Centroids[ind2,1],skernel,3) + smoothed[ind1,1] = savgol_filter(Centroids[ind1,1],25,3) + smoothed[ind2,1] = savgol_filter(Centroids[ind2,1],25,3) except: split = np.where(np.diff(tpf.time.mjd) > 0.5)[0][0] + 1 # ugly, but who cares @@ -421,15 +361,15 @@ def Smooth_motion(Centroids,tpf,skernel=25): ind1 = np.where(ind1 != 0)[0] ind2 = np.nansum(tpf.flux[split:],axis=(1,2)) ind2 = np.where(ind2 != 0)[0] + split - smoothed[ind1,0] = savgol_filter(Centroids[ind1,0],skernel//2+1,3) - smoothed[ind2,0] = savgol_filter(Centroids[ind2,0],skernel//2+1,3) + smoothed[ind1,0] = savgol_filter(Centroids[ind1,0],11,3) + smoothed[ind2,0] = savgol_filter(Centroids[ind2,0],11,3) - smoothed[ind1,1] = savgol_filter(Centroids[ind1,1],skernel//2+1,3) - smoothed[ind2,1] = savgol_filter(Centroids[ind2,1],skernel//2+1,3) + smoothed[ind1,1] = savgol_filter(Centroids[ind1,1],11,3) + smoothed[ind2,1] = savgol_filter(Centroids[ind2,1],11,3) except IndexError: - smoothed[:,0] = savgol_filter(Centroids[:,0],skernel,3) - smoothed[:,1] = savgol_filter(Centroids[:,1],skernel,3) + smoothed[:,0] = savgol_filter(Centroids[:,0],25,3) + smoothed[:,1] = savgol_filter(Centroids[:,1],25,3) return smoothed @@ -452,8 +392,6 @@ def smooth_zp(zp,time): smoothed displacement of the centroids """ - import matplotlib.pyplot as plt - smoothed = np.zeros_like(zp) * np.nan plt.figure() plt.plot(time,zp,'.') @@ -476,36 +414,36 @@ def smooth_zp(zp,time): return smoothed, err def grads_rad(flux): - """ - Calculates the radius of the flux from the gradient of the flux, and the double gradient of the flux. - - Parameters: - ---------- - flux: ArrayLike - An array of flux values - - Returns: - ------- - rad: ArrayLike - The radius of the fluxes - """ - rad = np.sqrt(np.gradient(flux)**2+np.gradient(np.gradient(flux))**2) - return rad + """ + Calculates the radius of the flux from the gradient of the flux, and the double gradient of the flux. + + Parameters: + ---------- + flux: ArrayLike + An array of flux values + + Returns: + ------- + rad: ArrayLike + The radius of the fluxes + """ + rad = np.sqrt(np.gradient(flux)**2+np.gradient(np.gradient(flux))**2) + return rad def grad_flux_rad(flux): """ - Calculates the radius of the flux from the gradient of the flux. - - Parameters: - ---------- - flux: ArrayLike - An array of flux values - - Returns: - ------- - rad: ArrayLike - The radius of the fluxes - """ + Calculates the radius of the flux from the gradient of the flux. + + Parameters: + ---------- + flux: ArrayLike + An array of flux values + + Returns: + ------- + rad: ArrayLike + The radius of the fluxes + """ rad = np.sqrt(flux**2+np.gradient(flux)**2) return rad @@ -537,32 +475,30 @@ def sn_lookup(name,time='disc',buffer=0,print_table=True, df = False): tr_list : list list of ra, dec, and sector that can be put into tessreduce. """ - tns = True - # try: - # url = 'https://api.astrocats.space/{}'.format(name) - # response = requests.get(url) - # json_acceptable_string = response.content.decode("utf-8").replace("'", "").split('\n')[0] - # d = json.loads(json_acceptable_string) - # if list(d.keys())[0] == 'message': - # #print(d['message']) - - # #return None - # tns = True - # else: - # disc_t = d[name]['discoverdate'][0]['value'] - # disc_t = Time(disc_t.replace('/','-')) - # max_t = d[name]['maxdate'][0]['value'] - # max_t = Time(max_t.replace('/','-')) - # ra = d[name]['ra'][-1]['value'] - # dec = d[name]['dec'][-1]['value'] - # tns = False - # except: - # tns = True + try: + url = 'https://api.astrocats.space/{}'.format(name) + response = requests.get(url) + json_acceptable_string = response.content.decode("utf-8").replace("'", "").split('\n')[0] + d = json.loads(json_acceptable_string) + if list(d.keys())[0] == 'message': + #print(d['message']) + + #return None + tns = True + else: + disc_t = d[name]['discoverdate'][0]['value'] + disc_t = Time(disc_t.replace('/','-')) + max_t = d[name]['maxdate'][0]['value'] + max_t = Time(max_t.replace('/','-')) + ra = d[name]['ra'][-1]['value'] + dec = d[name]['dec'][-1]['value'] + tns = False + except: + tns = True if tns: #print('!! Open SNe Catalog down, using TNS !!') - if (name[:2].lower() == 'sn') | (name[:2].lower() == 'at'): - name = name[2:] - url = f'https://www.wis-tns.org/object/{name}' + name = name[name.index('2'):] + url = f'https://www.wis-tns.org/object/{name}' # hard coding in that the event is in the 2000s headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'} result = requests.get(url, headers=headers) if result.ok: @@ -571,11 +507,11 @@ def sn_lookup(name,time='disc',buffer=0,print_table=True, df = False): disc_t = Time(result.text.split('Discovery Date
')[-1].split('<')[0]) max_t = deepcopy(disc_t) - # c = SkyCoord(ra,dec, unit=(u.hourangle, u.deg)) - # ra = c.ra.deg - # dec = c.dec.deg + c = SkyCoord(ra,dec, unit=(u.hourangle, u.deg)) + ra = c.ra.deg + dec = c.dec.deg - c = SkyCoord(ra,dec, unit=(u.deg, u.deg)) + c = SkyCoord(ra,dec, unit=(u.hourangle, u.deg)) ra = c.ra.deg dec = c.dec.deg @@ -766,17 +702,17 @@ def par_psf_initialise(flux,camera,ccd,sector,column,row,cutoutSize,loc,time_ind prf = create_psf(prf,cutoutSize) return prf, cutout -def par_psf_flux(image,error,prf,shift=[0,0],bkg_poly_order=3,kernel=None): +def par_psf_flux(image,prf,shift=[0,0]): if np.isnan(shift)[0]: shift = np.array([0,0]) - prf.psf_flux(image,error,ext_shift=shift,poly_order=bkg_poly_order,kernel=kernel) + prf.psf_flux(image,ext_shift=shift) return prf.flux, prf.eflux -def par_psf_full(cutout,error,prf,shift=[0,0],xlim=0.5,ylim=0.5): +def par_psf_full(cutout,prf,shift=[0,0],xlim=0.5,ylim=0.5): if np.isnan(shift)[0]: shift = np.array([0,0]) - prf.psf_position(cutout,error,ext_shift=shift,limx=xlim,limy=ylim) - prf.psf_flux(cutout,error) + prf.psf_position(cutout,ext_shift=shift,limx=xlim,limy=ylim) + prf.psf_flux(cutout) pos = [prf.source_x, prf.source_y] return prf.flux, prf.eflux, pos @@ -925,7 +861,6 @@ def Multiple_day_breaks(lc): #### CLUSTERING def Cluster_lc(lc): - from sklearn.cluster import OPTICS arr = np.array([np.gradient(lc[1]),lc[1]]) clust = OPTICS(min_samples=12, xi=.05, min_cluster_size=.05) opt = clust.fit(arr.T) @@ -1011,7 +946,6 @@ def _Get_im(ra, dec, size,color): return im def _Panstarrs_phot(ra,dec,size): - import matplotlib.pyplot as plt grey_im = _Get_im(ra,dec,size=size*4,color=False) colour_im = _Get_im(ra,dec,size=size*4,color=True) @@ -1034,7 +968,6 @@ def _Skymapper_phot(ra,dec,size): """ Gets g,r,i from skymapper. """ - import matplotlib.pyplot as plt size /= 3600 @@ -1150,9 +1083,6 @@ def Surface_names2model(names): for i,n in enumerate(names)]) def clip_background(bkg,mask,sigma=3,kern_size=5): - from sklearn.preprocessing import PolynomialFeatures - from sklearn.linear_model import LinearRegression - from sklearn.pipeline import make_pipeline regions, max_reg, ystep, xstep = subdivide_region(bkg) b2 = deepcopy(bkg) for j in range(2): @@ -1266,562 +1196,3 @@ def grad_clip_fill_bkg(bkg,sigma=3,max_size=1000): estimate = inpaint.inpaint_biharmonic(data,points) return estimate -def grad_clip(data,box_size=100): - """ - Perform a local sigma clip of points based on the gradient of the points. - Pixels with large gradients are contaminated by stars/galaxies. - - Inputs - ------ - data : array - 1d array of the data to clip - box_size : int - integer defining the box size to clip over - Output - ------ - gradind : bool - - """ - gradind = np.zeros_like(data) - - for i in range(len(data)): - if i < box_size//2: - d = data[:i+box_size//2] - elif len(data) - i < box_size//2: - d = data[i-box_size//2:] - else: - d = data[i-box_size//2:i+box_size//2] - - ind = np.isfinite(d) - d = d[ind] - if len(d) > 5: - gind = ~sigma_clip(np.gradient(abs(d))+d,sigma_lower=5,).mask - if i < box_size//2: - gradind[:i+box_size//2][ind] = gind - elif len(data) - i < box_size//2: - gradind[i-box_size//2:][ind] = gind - else: - gradind[i-box_size//2:i+box_size//2][ind] = gind - - gradind = gradind > 0 - return gradind - -def fit_strap(data,mask): - """ - interpolate over missing data - - """ - x = np.arange(0,len(data)) - y = data.copy() - p = np.ones_like(x) - if len(y[mask]) > 5: - p = interp1d(x[mask], y[mask],bounds_error=False,fill_value=np.nan,kind='linear') - p = p(x) - if np.isnan(p).any(): - p2 = interp1d(x[mask], y[mask],bounds_error=False,fill_value='extrapolate',kind='nearest') - p2 = p2(x) - p[np.isnan(p)] = p2[np.isnan(p)] - return p - -def parallel_strap_fit(frame,frame_bkg,frame_err,mask,repeats=3,tol=3): - norm = frame / frame_bkg - sind = np.where(np.nansum(mask,axis=0)>0)[0] - qe = np.ones_like(frame) - for i in sind: - y = frame[:,i] - d = abs(np.gradient(y)) - m, med, std = sigma_clipped_stats(d,maxiters=10) - nm = (d > med + std) * 1 - nm = np.convolve(nm,np.ones(3),mode='same') - nm = (nm == 0) - #for r in range(repeats): - q = fit_strap(norm[:,i],nm) - #q /= frame_bkg[:,i] - if len(y) > 110: - q = savgol_filter(q,101,1) - else: - mq = np.nanmedian(q) - q[:] = mq - - qe[:,i] = q - - #qe[:,np.nanmean((qe-1),axis=) < 5e-3] = 1 - return qe - - -def simulate_epsf(camera,ccd,sector,column,row,size=13,realizations=2000,oversample=3): - from photutils.psf import EPSFBuilder, EPSFStar, EPSFStars - - psfs = [] - randpos = np.random.uniform(-1,1,size=(2,realizations)) + 6 - prf_mod = TESS_PRF(cam=camera, ccd=ccd,sector=sector, - colnum=column,rownum=row) - - for i in range(len(randpos)): - psfs += [prf_mod.locate(randpos[0,i],randpos[1,i],(13,13))] - psfs = np.array(psfs) - - stars = [] - for i in range(len(psfs)): - stars += [EPSFStar(psfs[i],cutout_center=randpos[:,i])] - stars = EPSFStars(stars) - - epsf_builder = EPSFBuilder(oversampling=oversample, maxiters=20, progress_bar=False) - epsf, fitted_stars = epsf_builder(stars) - - return epsf - -def parallel_photutils(cutout,e_cutout,psf_phot,init_params=None,return_pos=False): - if np.nansum(abs(cutout)) > 0: - phot = psf_phot(cutout, error=e_cutout,init_params=init_params) - phot = phot.to_pandas() - f = phot[['flux_fit']].values[0]; ef = phot[['flux_err']].values[0] - pos = phot[['x_fit','y_fit']].values - epos = phot[['x_err','y_err']].values - if return_pos: - return f, ef, pos, epos - else: - return f, ef - #return float(phot[['flux_fit']].values), float(phot[['flux_err']].values) - else: - if return_pos: - pos = np.array([np.nan,np.nan]) - return np.array([np.nan]), np.array([np.nan]), pos, pos - else: - return np.array([np.nan]), np.array([np.nan]) - - -def fix_background_anomalies(bkg, mask, flux=None, bkg_prev=None, bkgmask=None, n_sigma=5.0, - box_size=16, anom_box=30, anom_box_fine=4, dilate_r=2, gauss_smooth=2, - sep_thresh=3.0, sep_snr_thresh=2.0, sep_validate=True, - high_bkg_frames=None, high_bkg_thresh=200.0, - bad_bkg_sigma=10.0, bad_bkg_min_area=100, n_jobs=-1): - """ - Fix anomalies (asteroids, cosmic rays) in a background cube. - - Pipeline: - Per frame (parallel): - 1. Subtract per-column additive excess on strap columns (bit 4). - 2. Fit a large-scale spatial trend with photutils Background2D. - 3. Flag pixels where |residual| > n_sigma * robust_sigma. - 4. Replace flagged (+ dilated) pixels with the trend value. - 5. Gaussian-smooth the result (strap excess held back). - Then (if flux and bkgmask supplied): - 6. Fit and subtract a residual surface from (flux - bkg). - Finally: - 7. Restore the strap column excess. - - Parameters - ---------- - bkg : ndarray (T, NY, NX) - mask : ndarray (NY, NX) or (T, NY, NX), bitmask — bit 1 = source, bit 4 = strap - flux : ndarray (T, NY, NX), optional — raw flux cube for residual surface step - bkgmask : ndarray (NY, NX) or (T, NY, NX), optional — NaN-where-excluded mask - n_sigma : float - box_size : int - dilate_r : int - gauss_smooth : float - n_jobs : int (passed to joblib; -1 = all cores) - - Returns - ------- - bkg_fixed : ndarray (T, NY, NX) - """ - from photutils.background import Background2D, MedianBackground - - T, NY, NX = bkg.shape - mask2d = mask[0] if mask.ndim == 3 else mask - if high_bkg_frames is None: - src_mask = ((mask2d & 1) == 0) & ((mask2d & 2) == 0) - ref = flux if flux is not None else bkg - masked_ref = ref * src_mask[np.newaxis].astype(float) - masked_ref[masked_ref == 0] = np.nan - frame_med = np.nanmedian(masked_ref, axis=(1, 2)) - high_bkg_frames = frame_med > high_bkg_thresh - else: - high_bkg_frames = np.asarray(high_bkg_frames, dtype=bool) - strap = (mask2d & 4).astype(bool) - good_cols = np.where(~strap.any(axis=0))[0] - strap_cols = np.where(strap.any(axis=0))[0] - has_straps = len(strap_cols) > 0 and len(good_cols) > 0 - bkgmask_arr = np.asarray(bkgmask) if bkgmask is not None else None - src_mask_2d = (mask2d & 1).astype(bool) - - # Scale box_size to the cutout — must fit at least 2 boxes per axis - eff_box = min(box_size, min(NY, NX) // 2) - eff_box = max(eff_box, 4) - - yr, xr = np.ogrid[-dilate_r:dilate_r+1, -dilate_r:dilate_r+1] - disk = xr**2 + yr**2 <= dilate_r**2 - yy, xx = np.mgrid[:NY, :NX] - def _process(i): - if bkgmask_arr is not None: - data_src = np.isnan(bkgmask_arr[i]) if bkgmask_arr.ndim == 3 else np.isnan(bkgmask_arr) - else: - data_src = src_mask_2d - phot_mask = strap | data_src - - frame = bkg[i].copy() - excess = np.zeros(len(strap_cols)) - - if has_straps and flux is not None: - _, excess, _ = sigma_clipped_stats((flux[i] - frame)[:, strap_cols], axis=0) - frame[:, strap_cols] -= excess - - try: - bkg2d = Background2D(frame, box_size=eff_box, filter_size=3, - mask=phot_mask, bkg_estimator=MedianBackground(), - exclude_percentile=50) - trend = bkg2d.background - except Exception: - trend = np.full_like(frame, np.nanmedian(frame)) - - resid = frame - trend - - valid_mask = ~phot_mask - - def _block_sigma(r, box): - sigma = np.full((NY, NX), np.inf, dtype=float) - row_starts = [min(r0, NY - box) for r0 in range(0, NY, box)] - col_starts = [min(c0, NX - box) for c0 in range(0, NX, box)] - for r0 in row_starts: - for c0 in col_starts: - r1, c1 = r0 + box, c0 + box - vals = r[r0:r1, c0:c1][valid_mask[r0:r1, c0:c1]] - if vals.size >= 4: - m = np.nanmedian(vals) - sigma[r0:r1, c0:c1] = 1.4826 * np.nanmedian(np.abs(vals - m)) - return sigma - - is_high_bkg = (high_bkg_frames is not None) and bool(high_bkg_frames[i]) - - sharp_mask = np.zeros((NY, NX), dtype=bool) - - if not is_high_bkg: - sigma_coarse = _block_sigma(resid, anom_box) - flagged_coarse = (np.abs(resid) > n_sigma * sigma_coarse) & ~phot_mask - - # Build SEP source mask on |Laplacian(frame)|. - import sep as _sep - lap_abs = np.abs(laplace(frame)).astype(np.float64) - _bkg = _sep.Background(lap_abs) - lap_sub = lap_abs - _bkg.back() - lap_err = _bkg.rms() - snr_map = lap_sub / (lap_err + 1e-10) - try: - objects = _sep.extract(lap_sub, thresh=sep_thresh, err=lap_err) - except Exception: - objects = [] - sep_mask = np.zeros((NY, NX), dtype=bool) - noise = np.nanmedian(lap_err) - for obj in objects: - ap_mask = np.zeros((NY, NX), dtype=bool) - _sep.mask_ellipse(ap_mask, obj['x'], obj['y'], obj['a'], obj['b'], obj['theta'], r=3.0) - if ap_mask.sum() == 0 or snr_map[ap_mask].mean() <= sep_snr_thresh: - continue - cx, cy = obj['x'], obj['y'] - true_r = None - for r in range(2, 20): - ann = (np.sqrt((xx - cx)**2 + (yy - cy)**2) >= r - 0.5) & \ - (np.sqrt((xx - cx)**2 + (yy - cy)**2) < r + 0.5) - if ann.sum() == 0: - break - if lap_sub[ann].mean() < noise: - true_r = r - 1 - break - else: - true_r = 19 - if true_r is None or true_r < 2 or true_r > 5: - continue - circ = np.sqrt((xx - cx)**2 + (yy - cy)**2) <= true_r - sep_mask |= circ - - lap_med = np.nanmedian(lap_abs) - lap_mad = np.nanmedian(np.abs(lap_abs - lap_med)) - is_sharp = lap_abs > lap_med + 3 * 1.4826 * lap_mad - - sharp_mask |= sep_mask - - if sep_validate: - edge_border = np.zeros((NY, NX), dtype=bool) - edge_border[0, :] = True; edge_border[-1, :] = True - edge_border[:, 0] = True; edge_border[:, -1] = True - labeled, n_comp = label(flagged_coarse) - smooth_mask = np.zeros((NY, NX), dtype=bool) - for comp_id in range(1, n_comp + 1): - comp = labeled == comp_id - if (comp & edge_border).any() and not (comp & sep_mask).any(): - smooth_mask |= comp - elif (comp & is_sharp).any() and (comp & sep_mask).any(): - sharp_mask |= comp - else: - smooth_mask |= comp - else: - sharp_mask |= flagged_coarse & is_sharp - - smooth_mask = flagged_coarse & ~sharp_mask - - # Fit fine Background2D excluding sharp anomaly pixels. - any_anom = sharp_mask.any() or smooth_mask.any() - if any_anom: - eff_fine = max(min(anom_box_fine, min(NY, NX) // 2), 4) - try: - bkg2d_fine = Background2D(frame, box_size=eff_fine, filter_size=3, - mask=phot_mask | sharp_mask, bkg_estimator=MedianBackground(), - exclude_percentile=50) - trend_fine = bkg2d_fine.background - except Exception: - trend_fine = trend - - if sharp_mask.any(): - frame[sharp_mask & ~phot_mask] = trend_fine[sharp_mask & ~phot_mask] - - resid_fine = frame - trend_fine - sigma_fine = _block_sigma(resid_fine, anom_box_fine) - flagged_fine = (np.abs(resid_fine) > n_sigma * sigma_fine) & ~phot_mask - confirmed = smooth_mask & flagged_fine - if confirmed.any(): - dilated = binary_dilation(confirmed, structure=disk) & ~phot_mask - frame[dilated] = trend_fine[dilated] - - # Blend toward bkg_prev before smoothing so smoothing is not overridden. - if bkg_prev is not None and flux is not None: - flux_frame = flux[i] - prev_frame = np.asarray(bkg_prev)[i] - resid_new = np.abs(flux_frame - frame) - resid_prev = np.abs(flux_frame - prev_frame) - delta = resid_new - resid_prev - _, _, scale = sigma_clipped_stats(resid_prev) - w = np.clip(delta / (scale + 1e-10), 0, 1) - w_zero = (w == 0) - if w_zero.any(): - w_med = median_filter(w_zero.astype(float), size=7) - diff_mask = w_zero & ~(w_med > 0.5) - w[w_med > 0.5] = 0 - if diff_mask.any(): - w[diff_mask] = np.nan - _, idx = distance_transform_edt(np.isnan(w), return_indices=True) - w[diff_mask] = w[tuple(idx[:, diff_mask])] - w[sharp_mask] = 0.0 - w[phot_mask] = 0.0 - frame = (1 - w) * frame + w * prev_frame - - smooth_sigma = 2.0 if is_high_bkg else gauss_smooth - fixed = gaussian_filter(frame, sigma=smooth_sigma) - - if has_straps and flux is not None: - _, excess, _ = sigma_clipped_stats((flux[i] - fixed)[:, strap_cols], axis=0) - fixed[:, strap_cols] += excess - - lap_abs = np.abs(laplace(fixed)) - lap_med = np.nanmedian(lap_abs) - lap_mad = np.nanmedian(np.abs(lap_abs - lap_med)) - high_lap = lap_abs > lap_med + bad_bkg_sigma * 1.4826 * lap_mad - labeled_lap, n_lap = label(high_lap) - bad_bkg_mask = np.zeros((NY, NX), dtype=bool) - for cid in range(1, n_lap + 1): - comp = labeled_lap == cid - if comp.sum() >= bad_bkg_min_area: - bad_bkg_mask |= comp - - return fixed, excess, sharp_mask, bad_bkg_mask - - results = Parallel(n_jobs=n_jobs, prefer='threads')(delayed(_process)(i) for i in range(T)) - bkg_fixed = np.array([r[0] for r in results]) - excesses = [r[1] for r in results] - sharp_masks = np.array([r[2] for r in results]) - bad_bkg_masks = np.array([r[3] for r in results]) # (T, NY, NX) bool - - if flux is not None and bkgmask is not None: - from astropy.stats import SigmaClip - sc = SigmaClip(sigma=3.0, maxiters=5) - res_box = min(20, min(NY, NX) // 2) - res_box = max(res_box, 4) - - def _fit_residual(residual, exclude_mask): - finite_vals = residual[~exclude_mask & np.isfinite(residual)] - med = np.nanmedian(finite_vals) - std = np.nanstd(finite_vals) - transient_mask = exclude_mask | (np.abs(residual - med) > 5 * std) - try: - b = Background2D(residual, box_size=res_box, filter_size=3, - sigma_clip=sc, bkg_estimator=MedianBackground(), - mask=transient_mask, fill_value=0.0) - corr = b.background - except Exception: - corr = np.full_like(residual, np.nanmedian(residual[~transient_mask])) - - # Apply Laplacian sharp/smooth classification to the correction. - # Only suppress corrections in sharp (point-like) regions — smooth - # background gradients should be applied. - corr_resid = residual - corr - _, corr_med, corr_std = sigma_clipped_stats(corr_resid[~exclude_mask]) - flagged = np.abs(corr_resid) > n_sigma * corr_std - if flagged.any(): - lap_abs = np.abs(laplace(corr_resid)) - lap_med = np.nanmedian(lap_abs) - lap_mad = np.nanmedian(np.abs(lap_abs - lap_med)) - is_sharp = lap_abs > lap_med + 3 * 1.4826 * lap_mad - labeled_c, n_c = label(flagged) - for cid in range(1, n_c + 1): - comp = labeled_c == cid - n_sp = (comp & is_sharp).sum() - if n_sp / comp.sum() >= 0.3: - corr[comp] = 0.0 - return corr - - residuals = flux - bkg_fixed - corrections = Parallel(n_jobs=n_jobs, prefer='threads')( - delayed(_fit_residual)( - residuals[i], - np.isnan(bkgmask_arr[i]) if bkgmask_arr.ndim == 3 else np.isnan(bkgmask_arr) - ) for i in range(T) - ) - bkg_fixed += np.array(corrections) - - # if has_straps: - # for i, excess in enumerate(excesses): - # use view to avoid numpy advanced-indexing shape ambiguity - # frame_view = bkg_fixed[i] - # frame_view[:, strap_cols] += excess - - return bkg_fixed, sharp_masks, bad_bkg_masks - - -def get_orbit_segments(times_mjd, sector=None, camera=None, vector_path=None, - gap_threshold=0.5): - """ - Assign each frame to an orbit segment. - - Tries to use TESSVectors (FFI cadence) to get official Segment assignments. - Falls back to splitting on time gaps > gap_threshold days if unavailable. - - Returns - ------- - segments : ndarray (T,) of int — 1-indexed orbit labels - """ - import pandas as pd - - if sector is not None and camera is not None: - fname = f'TessVectors_S{sector:03d}_C{camera}_FFI.csv' - url = ('https://heasarc.gsfc.nasa.gov/docs/tess/data/TESSVectors/' - f'Vectors/FFI_Cadence/{fname}') - df = None - if vector_path is not None: - local = os.path.join(vector_path, fname) - if os.path.isfile(local): - try: - df = pd.read_csv(local, comment='#', index_col=False) - except Exception: - df = None - if df is None: - try: - df = pd.read_csv(url, comment='#', index_col=False) - except Exception: - df = None - - if df is not None: - times_btjd = times_mjd - 56999.5 - vec_t = df['MidTime'].values - orbits = np.zeros(len(times_btjd), dtype=int) - for segment in np.unique(df['Segment'].values): - ind = np.where(df['Segment'].values == segment)[0] - o = (vec_t[ind[0]] - 0.1 <= times_btjd) & (times_btjd <= vec_t[ind[-1]] + 0.1) - orbits[o] = segment - return orbits - - # Fallback: split on large time gaps - diffs = np.diff(times_mjd) - breaks = np.where(diffs > gap_threshold)[0] + 1 - segments = np.ones(len(times_mjd), dtype=int) - for k, b in enumerate(breaks, start=2): - segments[b:] = k - return segments - - -def orbit_ref_subtract(flux, times_mjd, sector=None, camera=None, - vector_path=None, gap_threshold=0.5): - """ - Subtract a per-orbit reference from each orbit's frames. - - For each orbit the reference is the median stack of that orbit's frames, - subtracted only from frames belonging to that orbit. - - Parameters - ---------- - flux : ndarray (T, NY, NX) - times_mjd : ndarray (T,) - sector, camera: int — used to fetch TESSVectors orbit assignments - vector_path : str or None — local directory for cached TESSVectors files - gap_threshold : float — fallback gap size in days if TESSVectors unavailable - - Returns - ------- - result : ndarray (T, NY, NX) - segments : ndarray (T,) - orbit_refs : dict - """ - segments = get_orbit_segments(times_mjd, sector=sector, camera=camera, - vector_path=vector_path, - gap_threshold=gap_threshold) - orbs = np.unique(segments) - - orbit_refs = {s: np.nanmedian(flux[segments == s], axis=0) for s in orbs} - - result = np.empty_like(flux) - for s in orbs: - mask = segments == s - result[mask] = flux[mask] - orbit_refs[s] - - return result, segments, orbit_refs - - -def blend_dynamic_background(bkg_new, bkg_prev, flux, sigma=2.0, sharp_masks=None): - """Per-pixel blend bkg_new toward bkg_prev based on residual quality. - - For each pixel, compares |flux - bkg_new| vs |flux - bkg_prev|. Where - bkg_new leaves a larger residual than bkg_prev it is blended back toward - bkg_prev. The blend is soft: the transition is scaled by the per-frame - typical residual so noise-level differences do not trigger blending. - - Pixels in sharp_masks always use bkg_new (weight=0) — sharp anomaly - corrections are trusted unconditionally. - - Parameters - ---------- - bkg_new : np.ndarray (T, NY, NX) - bkg_prev : np.ndarray (T, NY, NX) - flux : np.ndarray (T, NY, NX) - sigma : float - sharp_masks : np.ndarray (T, NY, NX) bool, optional - - Returns - ------- - np.ndarray (T, NY, NX) - """ - bkg_new = np.array(bkg_new) - flux = np.array(flux) - resid_new = np.abs(flux - bkg_new) - resid_prev = np.abs(flux - bkg_prev) - delta = resid_new - resid_prev # positive = bkg_new is worse - _gauss_kernel = Gaussian2DKernel(1.0) - - out = bkg_new.copy() - for i in range(bkg_new.shape[0]): - _, _, scale = sigma_clipped_stats(resid_prev[i]) - w = np.clip(delta[i] / (sigma * scale + 1e-10), 0, 1) - - w_zero = (w == 0) - if w_zero.any(): - w_med = median_filter(w_zero.astype(float), size=7) - diff_mask = w_zero & ~(w_med > 0.5) - w[w_med > 0.5] = 0 - if diff_mask.any(): - w[diff_mask] = np.nan - w = interpolate_replace_nans(w, _gauss_kernel) - - if sharp_masks is not None: - w[sharp_masks[i]] = 0.0 - out[i] = (1 - w) * bkg_new[i] + w * bkg_prev[i] - return out - diff --git a/tessreduce/lastpercent.py b/tessreduce/lastpercent.py index 2a9486c..30f056b 100644 --- a/tessreduce/lastpercent.py +++ b/tessreduce/lastpercent.py @@ -1,9 +1,36 @@ import numpy as np from scipy.stats import pearsonr +from scipy.optimize import minimize from scipy.signal import savgol_filter +from scipy.interpolate import interp1d from joblib import Parallel, delayed from copy import deepcopy +def cor_minimizer(coeff,pix_lc,bkg_lc): + """ + Calculates the Pearson r correlation coefficent between the background subtracted lightcurve and the background itself. Takes inputs in a form for minimizing methods to be run on this function. + + Parameters: + ---------- + coeff: float + The multiplier on the background flux to be subtracted from the lightcurve. This is the variable being changed in any minimization. + pix_lc: ArrayLike + The full lightcurve of pixel flux data. Has a back + bkg_lc: ArrayLike + The background lightcurve, to be multiplied by coeff and subtracted from pix_lc + + Returns: + ------- + corr: float + The absolute value of the Pearson r correlation coefficent between the background subtracted lightcurve and the background. + """ + lc = pix_lc - coeff * bkg_lc + ind = np.isfinite(lc) & np.isfinite(bkg_lc) + #bkgnorm = bkg_lc/np.nanmax(bkg_lc) + #pixnorm= (lc - np.nanmedian(lc)) + #pixnorm = pixnorm / np.nanmax(abs(pixnorm)) + corr = pearsonr(lc[ind],bkg_lc[ind])[0] + return abs(corr) def _parallel_correlation(pixel,bkg,arr,coord,smth_time): """ @@ -63,111 +90,156 @@ def _find_bkg_cor(tess,cores): cors[coord[:,0],coord[:,1]] = cor return cors -def _correct_pixel_correlation(flux, bkg, bright_pct=70, max_coeff=0.1): - """Remove the linear flux-background correlation for a single pixel. - - Fits alpha = sum(flux * bkg_centered) / sum(bkg_centered²) on the - brightest `bright_pct`% of background frames, then subtracts - alpha * bkg_centered from the full time series. The correction is only - applied when it actually reduces the Pearson |r|. +def _address_peaks(flux,bkg,std): + """ + Filters the upper 30% of the background values and their corresponding flux values. The fit to the background involves a minimization of the correlation coefficents and an interpolated savgol filter of the fluxes. The fluxes are modified by the same savgol filter, and the median of the lower 16% of the std. - Parameters + Parameters: ---------- - flux : array (T,) - bkg : array (T,) - bright_pct : float - Percentile threshold for "scattered-light" frames used in fitting. - max_coeff : float - Hard cap on |alpha| to prevent overcorrection. - - Returns + flux: ArrayLike + The flux array of interest + bkg: ArrayLike + The background flux array corresponding to flux. + std: ArrayLike + An array of the standard deviations of the background + + Returns: ------- - corrected flux : array (T,) — same as input if correction not helpful. + new_flux: ArrayLike + The modified flux array. If there is nothing to modify, new_flux==flux. + new_bkg: ArrayLike + The modified background array. If there is nothing to modify, new_bkg==bkg. """ - nn = np.isfinite(flux) & np.isfinite(bkg) - if nn.sum() < 10: - return flux.copy() - - f = flux[nn] + + nn = np.isfinite(flux) b = bkg[nn] + f = flux[nn] + bkg_ind = (b > np.percentile(b,70)) #& (bb < np.percentile(bb,95)) + split = np.where(np.diff(np.where(bkg_ind)[0]) > 100)[0][0] + new_bkg = deepcopy(bkg) + new_flux = deepcopy(flux) + counter = np.arange(len(b[bkg_ind]),dtype=int) + for i in range(2): + if i == 0: + split_ind = counter[split:] + else: + split_ind = counter[:split] + ff = deepcopy(f[bkg_ind][split_ind]) + s = std[nn][bkg_ind][split_ind] + med_ind = s < np.percentile(s,16) + med = np.nanmedian(ff[med_ind]) + ff -= med + + x0 =[1e-3] + fit = minimize(cor_minimizer,x0,(ff,b[bkg_ind][split_ind]),method='Powell') + ff -= b[bkg_ind][split_ind]*fit.x + + + bound_ind = (ff < s*2) & (ff > -s*2) + if np.sum(bound_ind*1) > 10: + xf = np.arange(len(ff)) + + sav = savgol_filter(ff[bound_ind],len(ff[bound_ind])//2 + 1,3) + interp = interp1d(xf[bound_ind],sav,bounds_error=False,fill_value='extrapolate') + sav = interp(xf) + + #plt.figure() + #plt.plot(new_flux[nn][bkg_ind][split_ind]) + #plt.plot(new_bkg[nn][bkg_ind][split_ind]*fit.x + sav) + #plt.plot(new_bkg[nn][bkg_ind][split_ind]*fit.x) + #plt.plot(sav) + #plt.plot(ff-sav,'--') + else: + sav = 0 + indo = np.arange(len(flux)) + indo = indo[nn][bkg_ind][split_ind] + + new_bkg[indo] += new_bkg[nn][bkg_ind][split_ind]*fit.x + sav + new_flux[indo] = ff - sav + med + return new_flux, new_bkg + +def _calc_bkg_std(data,coord,d=6): + """ + Calculates the background standard deviation of data in a rectangle of size d pixels around the coord point given. - # Centre bkg on the quiet-period level so the correction is zero when - # there is no scattered light. - bkg_quiet = np.nanmedian(b[b < np.percentile(b, 30)]) - b_centered = b - bkg_quiet - - bright = b > np.percentile(b, bright_pct) - if bright.sum() < 5: - return flux.copy() - - # OLS with no intercept: flux ≈ alpha * bkg_centered - denom = np.nansum(b_centered[bright] ** 2) - if denom == 0: - return flux.copy() - alpha = np.clip(np.nansum(f[bright] * b_centered[bright]) / denom, - -max_coeff, max_coeff) - - corrected = flux.copy() - corrected[nn] = f - alpha * b_centered - - # Validate: only keep if |r| on bright frames actually decreases - r_before = abs(pearsonr(f[bright], b[bright])[0]) - r_after = abs(pearsonr(corrected[nn][bright], b[bright])[0]) - if r_after >= r_before: - return flux.copy() - - return corrected - + Parameters: + ---------- + data: ArrayLike + A 2d Array of flux values to calculate the standard deviation of. + coord: ArrayLike (shape(2,)) + The y, x coordinate to calculate the standard deviation around. + d: int, optional + The size of the rectangle to have the standard deviation calculates in. If the pairing of coord and d would result in a rectangle indexing outside of data, this is corrected for, so d is the maximum size of the rectangle, and will give a square box if no corrections are needed. Default is 6. -def multi_correlation_cor(tess, limit=0.8, cores=7): - """Remove residual flux-background correlation for highly correlated pixels. + Returns: + ------- + std: float + The standard deviation of data at and around coord. + """ - For each pixel where |Pearson r| > limit (computed on the upper 30% of - background frames), fits a bounded linear coefficient and subtracts the - correlated component from the full flux time series. Only pixels flagged - as sources or saturated stars in the catalogue mask are corrected — - background pixels have intrinsic scattered-light correlation that should - not be removed here. + y = coord[0]; x = coord[1] + ylow = y-d; yhigh=y+d+1 + if ylow < 0: + ylow=0; + if yhigh > data.shape[0]: + yhigh=data.shape[0] + xlow = x-d; xhigh=x+d + if xlow < 0: + xlow=0; + if xhigh > data.shape[0]: + xhigh=data.shape[0] + + std = np.nanstd(data[:,ylow:yhigh,xlow:xhigh],axis=(1,2)) + return std + + +def multi_correlation_cor(tess,limit=0.8,cores=7): + """ + Corrects for correlation coefficents larger than limit. If the flux and the background of tess are correlated (absolute value of correlation coefficent, |r|) to a level higher than limit, a fit to minimize this coefficent is preformed, and the new background and flux values are returned - Parameters + Parameters: ---------- - tess : TESSreduce object - limit : float (default 0.8) - cores : int (default 7) + tess: TESSreduce Object - Returns + limit: float, optional + The largest acceptable |r| before any modifications are needed. Should be in range (0,1) for comparison to |r| to make any sense. Default is 0.8. + cores: int, optional + The number of cores to use for multiprocessing. Default is 7. + + Returns: ------- - flux : array (T, NY, NX) - bkg : array (T, NY, NX) - """ - cors = _find_bkg_cor(tess, cores=cores) - - # Restrict to source / saturated pixels (mask bits 1 and 2). - # Pure background pixels have high |r| because of scattered light and - # do not need — or benefit from — this correction. - mask2d = tess.mask[0] if tess.mask.ndim == 3 else tess.mask - src_pix = (mask2d & 3) > 0 - - y, x = np.where((cors > limit) & src_pix) + flux: ArrayLike + The modified flux array, after any needed changes have been made. If nothing is needed to be changed, or the modification breaks, flux == tess.flux. + bkg: + The modified background array, after any needed changes have been made. If nothing is needed to be changed, or the modification breaks, bkg == tess.bkg. + """ + cors = _find_bkg_cor(tess,cores=cores) + y,x = np.where(cors > limit) flux = deepcopy(tess.flux) bkg = deepcopy(tess.bkg) - - if len(y) == 0: - return flux, bkg - - results = Parallel(n_jobs=cores)( - delayed(_correct_pixel_correlation)( - tess.flux[:, y[i], x[i]], - tess.bkg[:, y[i], x[i]], - ) - for i in range(len(y)) - ) - - for i, corrected in enumerate(results): - flux[:, y[i], x[i]] = corrected - - return flux, bkg + if len(y > 0): + try: + coord = np.c_[y,x] + dat = tess.bkg + stds = np.zeros_like(dat) + std = Parallel(n_jobs=cores)(delayed(_calc_bkg_std)(dat,coord[i])for i in range(len(coord))) + std = np.array(std) + stds[:,coord[:,0],coord[:,1]] = std.T + + new_flux, new_bkg = zip(*Parallel(n_jobs=cores)(delayed(_address_peaks) + (tess.flux[:,coord[i,0],coord[i,1]], + tess.bkg[:,coord[i,0],coord[i,1]], + stds[:,coord[i,0],coord[i,1]]) + for i in range(len(coord)))) + + new_bkg = np.array(new_bkg) + new_flux = np.array(new_flux) + flux[:,coord[:,0],coord[:,1]] = new_flux.T + bkg[:,coord[:,0],coord[:,1]] = new_bkg.T + except: + bad = 1 + return flux, bkg diff --git a/tessreduce/psf_photom.py b/tessreduce/psf_photom.py index d2e8073..0821292 100644 --- a/tessreduce/psf_photom.py +++ b/tessreduce/psf_photom.py @@ -2,7 +2,6 @@ from skimage.util.shape import view_as_windows from scipy.optimize import minimize from scipy.ndimage import shift -from scipy.signal import fftconvolve """ PSF photometry class repurposed from Starkiller by Hugh Roxburgh @@ -91,7 +90,7 @@ def source(self,shiftx=0,shifty=0,ext_shift=[0,0]): psf = shift(psf,ext_shift) self.psf = psf/np.nansum(psf) - def minimize_position(self,coeff,image,error,ext_shift):#,surface=True,order=2): + def minimize_position(self,coeff,image,ext_shift): """ Applies an exponential function using psf residuals to optimise the psf fit. @@ -114,15 +113,7 @@ def minimize_position(self,coeff,image,error,ext_shift):#,surface=True,order=2): optimization model used for psf fitting """ - # if surface: - # x = np.arange(image.shape[1]) - # y = np.arange(image.shape[0]) - # yy,xx = np.meshgrid(y,x) - # plane_coeff = coeff[2:] - # s = polynomial_surface(xx,yy,plane_coeff,order) - # else: - # s = 0 - + self.source_x = coeff[0] self.source_y = coeff[1] @@ -130,11 +121,11 @@ def minimize_position(self,coeff,image,error,ext_shift):#,surface=True,order=2): self.source(shiftx = self.source_x, shifty = self.source_y,ext_shift=ext_shift) # -- calculate residuals -- # - diff = abs(image - self.psf)**2 - residual = np.nansum(diff/error) - return residual#np.exp(residual) + diff = abs(image - self.psf) + residual = np.nansum(diff) + return np.exp(residual) - def psf_position(self,image,error,limx=0.8,limy=0.8,ext_shift=[0,0]):#,surface=False,order=2): + def psf_position(self,image,limx=1,limy=1,ext_shift=[0,0]): """ Finds the optimal psf fit @@ -158,33 +149,16 @@ def psf_position(self,image,error,limx=0.8,limy=0.8,ext_shift=[0,0]):#,surface=F Optimal psf fit to input image """ - if error is None: - error = np.ones_like(image) - #brightloc = - if np.nansum(image) > 0: - if np.isfinite(ext_shift).all(): - ext_shift[0] = 0; ext_shift[1] = 0 - normimage = image / np.nansum(image) # normalise the image - - # if surface: - # num_coeffs = (poly_order + 1) * (poly_order + 2) // 2 - # coeff = np.zeros(num_coeffs + 2) - # coeff[0] = self.source_x; coeff[1] = self.source_y - # lims = [[-limx,limx],[-limy,limy]] - # for i in range(num_coeffs): - # lims += [-np.inf,np.inf] - # else: - coeff = [self.source_x,self.source_y] - lims = [[-limx,limx],[-limy,limy]] - - # -- Optimize -- # - res = minimize(self.minimize_position, coeff, args=(normimage,error,ext_shift), method='Powell',bounds=lims) - print('Optimal PSF shift: ', res.x) - self.psf_fit = res - else: - self.psf_fit = None - def minimize_psf_flux(self,coeff,image,error=None,surface=True,order=2,kernel=None): + normimage = image / np.nansum(image) # normalise the image + coeff = [self.source_x,self.source_y] + lims = [[-limx,limx],[-limy,limy]] + + # -- Optimize -- # + res = minimize(self.minimize_position, coeff, args=(normimage,ext_shift), method='Powell',bounds=lims) + self.psf_fit = res + + def minimize_psf_flux(self,coeff,image,surface=True,order=2): """ @@ -215,13 +189,10 @@ def minimize_psf_flux(self,coeff,image,error=None,surface=True,order=2,kernel=No s = polynomial_surface(xx,yy,plane_coeff,order) else: s = 0 - if kernel is not None: - self.psf = fftconvolve(self.psf, kernel, mode='same') - - res = np.nansum((image - self.psf*coeff[0] - s)**2/error) + res = np.nansum((image - self.psf*coeff[0] - s)**2) return res - def psf_flux(self,image,error=None,ext_shift=None,surface=True,poly_order=3,kernel=None): + def psf_flux(self,image,ext_shift=None,surface=True,poly_order=3): """ @@ -246,15 +217,15 @@ def psf_flux(self,image,error=None,ext_shift=None,surface=True,poly_order=3,kern residual of optimal psf flux fit """ - if error is None: - error = np.ones_like(image) + if self.psf is None: self.source(shiftx=self.source_x,shifty=self.source_y) - if (ext_shift is not None) & np.isfinite(ext_shift).all(): + if ext_shift is not None: self.source(ext_shift=ext_shift) mask = np.zeros_like(self.psf) mask[self.psf > np.nanpercentile(self.psf,90)] = 1 f0 = np.nansum(image*mask) + # print(f0) #bkg = np.nanmedian(image[~mask.astype(bool)]) #image = image - bkg @@ -265,10 +236,8 @@ def psf_flux(self,image,error=None,ext_shift=None,surface=True,poly_order=3,kern else: initial = f0 - res = minimize(self.minimize_psf_flux,initial,args=(image,error,surface,poly_order,kernel),method='BFGS') - #res = minimize(self.minimize_psf_flux,initial,args=(image,error,surface,poly_order,kernel),method='Powell') + res = minimize(self.minimize_psf_flux,initial,args=(image,surface,poly_order),method='BFGS') error = np.sqrt(np.diag(res['hess_inv'])) - self.res = res self.flux = res.x[0] self.eflux = error[0] diff --git a/tessreduce/rescale_straps.py b/tessreduce/rescale_straps.py index 85dfc08..5f1e3b5 100755 --- a/tessreduce/rescale_straps.py +++ b/tessreduce/rescale_straps.py @@ -50,44 +50,35 @@ def grad_clip(data,box_size=100): gradind = gradind > 0 return gradind -def fit_strap(data, percentile=20): +def fit_strap(data): """ - Interpolate over stellar-contaminated rows in strap (or neighbour) columns. + interpolate over missing data - Stellar flux is strictly additive, so the true background always sits at - the *low* end of the pixel-value distribution in a strap column. The - original 50th-percentile threshold discards half the data unconditionally - and fails completely when more than half of the rows in the column are - contaminated by stars (the median is then elevated into the stellar - signal). Using a lower percentile (default 20th) means contamination must - exceed 80 % of rows before the threshold is biased into stellar flux, - making rejection far more robust in crowded fields. - - Parameters - ---------- - data : array_like - 1-D array of pixel values along a single column. - percentile : float, optional - Percentile of the finite pixel values used as the upper clip limit. - Values at or above this level are treated as stellar contamination and - replaced with NaN before interpolation. Default is 20 (was 50). """ - + x = np.arange(0,len(data)) y = data.copy() p =np.ones_like(x) * np.nan + #y[~grad_clip(y)] = np.nan if len(y[np.isfinite(y)]) > 10: - lim = np.percentile(y[np.isfinite(y)], percentile) + lim = np.percentile(y[np.isfinite(y)],50) y[y >= lim] = np.nan finite = np.isfinite(y) - + if len(y[finite]) > 5: finite = np.isfinite(y) - p = interp1d(x[finite], y[finite],bounds_error=False,fill_value=np.nan,kind='linear') + #y = median_clipping(y) + finite = np.where(finite)[0] + finite = np.isfinite(y) + #y[finite] = savgol_filter(y[finite],11,3) + p = interp1d(x[finite], y[finite],bounds_error=False,fill_value=np.nan,kind='nearest') p = p(x) + #p[np.isfinite(p)] = savgol_filter(p[np.isfinite(p)],31,1) return p +from copy import deepcopy + def calc_strap_factor(i,breaks,size,av_size,normals,data): qe = np.ones_like(data) * 1. * np.nan b = int(breaks[i]) diff --git a/tessreduce/sector_mjd.csv b/tessreduce/sector_mjd.csv index d24941b..3367f7f 100755 --- a/tessreduce/sector_mjd.csv +++ b/tessreduce/sector_mjd.csv @@ -1,104 +1,84 @@ -Sector,mjd_start,mjd_end -1,58324.81597222222,58352.68402777778 -2,58353.60763888889,58381.020833333336 -3,58382.225694444445,58408.875 -4,58410.40625,58436.35763888889 -5,58437.48263888889,58463.79513888889 -6,58464.711805555555,58489.552083333336 -7,58491.131944444445,58515.59375 -8,58516.84722222222,58541.506944444445 -9,58542.72222222222,58567.98263888889 -10,58568.9375,58595.1875 -11,58596.27777777778,58623.399305555555 -12,58624.45486111111,58652.399305555555 -13,58653.42013888889,58681.864583333336 -14,58682.854166666664,58709.711805555555 -15,58710.864583333336,58736.916666666664 -16,58738.15277777778,58762.82638888889 -17,58764.18402777778,58789.20138888889 -18,58790.15625,58814.538194444445 -19,58815.583333333336,58840.65625 -20,58842.00347222222,58868.32986111111 -21,58869.93402777778,58897.288194444445 -22,58898.805555555555,58926.0 -23,58927.604166666664,58954.381944444445 -24,58955.29513888889,58981.788194444445 -25,58983.131944444445,59008.8125 -26,59009.76736111111,59034.64236111111 -27,59035.77777777778,59060.149305555555 -28,59061.350694444445,59086.604166666664 -29,59087.739583333336,59113.94097222222 -30,59115.385416666664,59142.729166666664 -31,59144.01388888889,59171.53472222222 -32,59172.572916666664,59199.739583333336 -33,59201.23263888889,59227.07986111111 -34,59228.25,59253.572916666664 -35,59254.489583333336,59279.48611111111 -36,59280.40277777778,59305.49652777778 -37,59306.739583333336,59332.086805555555 -38,59333.354166666664,59360.05902777778 -39,59361.270833333336,59389.225694444445 -40,59390.15277777778,59418.36111111111 -41,59419.489583333336,59446.086805555555 -42,59447.19097222222,59472.666666666664 -43,59473.666666666664,59498.395833333336 -44,59499.6875,59523.947916666664 -45,59525.006944444445,59550.131944444445 -46,59551.06597222222,59578.27777777778 -47,59579.302083333336,59606.447916666664 -48,59607.43402777778,59635.493055555555 -49,59636.97222222222,59663.822916666664 -50,59664.770833333336,59691.01736111111 -51,59692.447916666664,59717.041666666664 -52,59718.135416666664,59742.583333333336 -53,59743.49652777778,59768.48611111111 -54,59769.399305555555,59795.635416666664 -55,59796.600694444445,59823.770833333336 -56,59824.756944444445,59838.020833333336 -57,59852.854166666664,59866.75347222222 -58,59881.82986111111,59895.5625 -59,59909.76388888889,59922.854166666664 -60,59936.40277777778,59949.274305555555 -61,59962.29861111111,59974.70486111111 -62,59987.94097222222,60000.430555555555 -63,60013.868055555555,60026.899305555555 -64,60040.614583333336,60054.586805555555 -65,60068.239583333336,60082.98263888889 -66,60097.17361111111,60111.48263888889 -67,60126.14236111111,60139.756944444445 -68,60154.11111111111,60167.77777777778 -69,60181.854166666664,60194.5 -70,60207.854166666664,60220.631944444445 -71,60233.53472222222,60246.51388888889 -72,60259.68402777778,60272.506944444445 -73,60285.29861111111,60298.447916666664 -74,60312.364583333336,60325.354166666664 -75,60339.28472222222,60353.0625 -76,60367.197916666664,60380.89236111111 -77,60394.98611111111,60408.774305555555 -78,60423.26388888889,60437.166666666664 -79,60452.038194444445,60465.10763888889 -80,60479.38888888889,60492.850694444445 -81,60506.052083333336,60519.07986111111 -82,60532.89236111111,60544.96875 -83,60558.927083333336,60571.21527777778 -84,60584.09027777778,60596.805555555555 -85,60610.055555555555,60622.739583333336 -86,60635.760416666664,60649.114583333336 -87,60662.541666666664,60675.947916666664 -88,60689.65277777778,60703.395833333336 -89,60717.63888888889,60732.45138888889 -90,60746.65972222222,60760.239583333336 -91,60774.791666666664,60788.76388888889 -92,60802.47222222222,60815.98611111111 -93,60829.35763888889,60842.63888888889 -94,60855.76388888889,60868.23611111111 -95,60881.833333333336,60894.17361111111 -96,60907.274305555555,60919.989583333336 -97,60933.15972222222,60946.37152777778 -98,60988.0,61002.302083333336 -99,61045.614583333336,61059.23611111111 -100,61073.493055555555,61086.78125 -101,61100.180555555555,61113.04513888889 -102,61126.520833333336,61139.024305555555 -103,61151.53125,61164.729166666664 +Sector,Dates,mjd_start,mjd_end +1,07/25/18-08/22/18,58324,58352 +2,08/22/18-09/20/18,58352,58381 +3,09/20/18-10/18/18,58381,58409 +4,10/18/18-11/15/18,58409,58437 +5,11/15/18-12/11/18,58437,58463 +6,12/11/18-01/07/19,58463,58490 +7,01/07/19-02/02/19,58490,58516 +8,02/02/19-02/28/19,58516,58542 +9,02/28/19-03/26/19,58542,58568 +10,03/26/19-04/22/19,58568,58595 +11,04/22/19-05/21/19,58595,58624 +12,05/21/19-06/19/19,58624,58653 +13,06/19/19-07/18/19,58653,58682 +14,07/18/19-08/15/19,58682,58710 +15,08/15/19-09/11/19,58710,58737 +16,09/11/19-10/07/19,58737,58763 +17,10/07/19-11/02/19,58763,58789 +18,11/02/19-11/27/19,58789,58814 +19,11/27/19-12/24/19,58814,58841 +20,12/24/19-01/21/20,58841,58869 +21,01/21/20-02/18/20,58869,58897 +22,02/18/20-03/18/20,58897,58926 +23,03/18/20-04/16/20,58926,58955 +24,04/16/20-05/13/20,58955,58982 +25,05/13/20-06/08/20,58982,59008 +26,06/08/20-07/04/20,59008,59034 +27,07/04/20-07/30/20,59034,59060 +28,07/30/20-08/26/20,59060,59087 +29,08/26/20-09/22/20,59087,59114 +30,09/22/20-10/21/20,59114,59143 +31,10/21/20-11/19/20,59143,59172 +32,11/19/20-12/17/20,59172,59200 +33,12/17/20-01/13/21,59200,59227 +34,01/13/21-02/09/21,59227,59254 +35,02/09/21-03/07/21,59254,59280 +36,03/07/21-04/02/21,59280,59306 +37,04/02/21-04/28/21,59306,59332 +38,04/28/21-05/26/21,59332,59360 +39,05/26/21-06/24/21,59360,59389 +40,06/24/21-07/23/21,59389,59418 +41,07/23/21-08/20/21,59418,59446 +42,08/20/21-09/16/21,59446,59473 +43,09/16/21-10/12/21,59473,59499 +44,10/12/21-11/06/21,59499,59524 +45,11/06/21-12/02/21,59524,59550 +46,12/02/21-12/30/21,59550,59578 +47,12/30/21-01/28/22,59578,59607 +48,01/28/22-02/26/22,59607,59636 +49,02/26/22-03/26/22,59636,59664 +50,03/26/22-04/22/22,59664,59691 +51,04/22/22-05/18/22,59691,59717 +52,05/18/22-06/13/22,59717,59743 +53,06/13/22-07/09/22,59743,59769 +54,07/09/22-08/05/22,59769,59796 +55,08/05/22-09/01/22,59796,59823 +56,09/01/22-09/30/22,59823,59852 +57,09/30/22-10/29/22,59852,59881 +58,10/29/22-11/26/22,59881,59909 +59,11/26/22-12/23/22,59909,59936 +60,12/23/22-01/18/23,59936,59962 +61,01/18/23-02/12/23,59962,59987 +62,02/12/23-03/10/23,59987,60013 +63,03/10/23-04/06/23,60013,60040 +64,04/06/23-05/04/23,60040,60068 +65,05/04/23-06/02/23,60068,60097 +66,06/02/23-07/01/23,60097,60126 +67,07/01/23-07/29/23,60126,60154 +68,07/29/23-08/25/23,60154,60181 +69,08/25/23-09/20/23,60181,60207 +70,20/09/23-16/10/23,60207,60233 +71,16/10/23-11/11/23,60233,60259 +72,11/11/23-07/12/23,60259,60285 +73,07/12/23-03/01/24,60285,60312 +74,03/01/24-30/01/24,60312,60339 +75,30/01/24-26/02/24,60339,60366 +76,26/02/24-26/03/24,60366,60395 +77,26/03/24-23/04/24,60395,60423 +78,23/04/24-21/05/24,60423,60451 +79,21/05/24-18/06/24,60451,60479 +80,18/06/24-15/07/24,60479,60506 +81,15/07/24-10/08/24,60506,60532 +82,10/08/24-05/09/24,60532,60558 +83,05/09/24-01/10/24,60558,60584 \ No newline at end of file diff --git a/tessreduce/sep_aligner.py b/tessreduce/sep_aligner.py deleted file mode 100644 index 4b58475..0000000 --- a/tessreduce/sep_aligner.py +++ /dev/null @@ -1,1587 +0,0 @@ -""" -sep_aligner.py -============== -A tessreduce-compatible image alignment class using SEP source extraction -and 3×3 PSF-core stamp minimisation. - -Usage inside tessreduce ------------------------ -Drop this file next to tessreduce.py (or anywhere on sys.path) and call: - - from sep_aligner import SepAligner - - # Standalone: - aligner = SepAligner(tr.ref, tr.flux, n_jobs=-1) - aligner.run() - tr.shift = aligner.shift # hand shifts back to tessreduce - tr.shift_images() # tessreduce applies them - - # Or plug into the shift_method dispatch in tessreduce.reduce(): - # elif self._shift_method == 'sep_core': - # SepAligner.from_tessreduce(self).run() - -Interface contract with tessreduce ------------------------------------ -tessreduce.shift_images() expects self.shift to be (T, 2) float32 where - shift[t] = [row_shift, col_shift] ≡ [dy, dx] -and applies scipy.ndimage.shift(frame, [dy, dx]) -i.e. a POSITIVE dy moves the image content DOWN (row += dy). - -SepAligner measures dx, dy as (science − reference) pixel displacement and -stores them with the same sign convention so tessreduce.shift_images() will -call shift(frame, [-dy, -dx]) ... actually tessreduce calls -shift(frame, [+dy, +dx]) so we store the NEGATIVE of our measured offset. -See _build_shift_array() for details. -""" - -from __future__ import annotations - -import warnings -from typing import Optional - -import numpy as np -import pandas as pd -import sep -from joblib import Parallel, delayed -from scipy.interpolate import RectBivariateSpline -from scipy.ndimage import shift as nd_shift -from scipy.optimize import minimize -from scipy.spatial import cKDTree - - -fig_width = 240.0 / 72.27 # matches tessreduce figure sizing convention - - -# ───────────────────────────────────────────────────────────────────────────── -# Internal helpers (module-level so joblib can pickle them) -# ───────────────────────────────────────────────────────────────────────────── - -def _adaptive_params(shape: tuple[int, int]) -> dict: - """Scale stamp / extraction params to image size.""" - H, W = shape - minsize = min(H, W) - stamp_half = max(3, min(7, minsize // 6)) - core_half = 2 if stamp_half >= 3 else 0 - minarea = 3 if minsize < 80 else 5 - match_radius = max(2.0, min(3.0, minsize * 0.05)) - coarse_range = max(0.3, min(1.0, minsize * 0.03)) - return dict(stamp_half=stamp_half, core_half=core_half, - minarea=minarea, match_radius=match_radius, - coarse_range=coarse_range) - - -def _extract(arr: np.ndarray, thresh: float = 3.0, minarea: int = 5): - """Background-subtract and extract sources. Returns (sub, src).""" - a = np.ascontiguousarray(arr, dtype=np.float64) - bkg = sep.Background(a) - sub = a - bkg - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - src = sep.extract(sub, thresh, err=bkg.globalrms, minarea=minarea) - return sub, src - - -def _select_stars(src_ref, src_img, sub_ref, sub_img, - sat_frac: float = 0.7, - ell_max: float = 0.5, - var_thresh: float = 0.05, - match_radius: float = 3.0, - flag_max: int = 0, - edge_margin: int = 3, - pixel_mask: Optional[np.ndarray] = None) -> tuple[np.ndarray, np.ndarray]: - """ - Return (ri, ii) index arrays into src_ref / src_img for matched pairs that - are round, unflagged, unsaturated, flux-stable, and not within - edge_margin pixels of any border. Sources whose centre pixel has - pixel_mask True are also excluded. - """ - empty = np.array([], dtype=int) - if len(src_ref) == 0 or len(src_img) == 0: - return empty, empty - - H, W = sub_ref.shape - sat_level = sat_frac * max(float(sub_ref.max()), float(sub_img.max())) - m = edge_margin - - ref_ok = ((src_ref['x'] >= m) & (src_ref['x'] <= W - 1 - m) & - (src_ref['y'] >= m) & (src_ref['y'] <= H - 1 - m)) - img_ok = ((src_img['x'] >= m) & (src_img['x'] <= W - 1 - m) & - (src_img['y'] >= m) & (src_img['y'] <= H - 1 - m)) - - if pixel_mask is not None: - rx = np.clip(np.round(src_ref['x']).astype(int), 0, W - 1) - ry = np.clip(np.round(src_ref['y']).astype(int), 0, H - 1) - ix = np.clip(np.round(src_img['x']).astype(int), 0, W - 1) - iy = np.clip(np.round(src_img['y']).astype(int), 0, H - 1) - ref_ok &= ~pixel_mask[ry, rx] - img_ok &= ~pixel_mask[iy, ix] - - src_r = src_ref[ref_ok]; ri_orig = np.where(ref_ok)[0] - src_i = src_img[img_ok]; ii_orig = np.where(img_ok)[0] - - if len(src_r) == 0 or len(src_i) == 0: - return empty, empty - - tree = cKDTree(np.c_[src_i['x'], src_i['y']]) - dist, idx = tree.query(np.c_[src_r['x'], src_r['y']], - k=1, distance_upper_bound=match_radius) - valid = dist < match_radius - ri_in = np.where(valid)[0] - ii_in = idx[valid] - - if len(ri_in) == 0: - return empty, empty - - flux_ratio = (src_i['flux'][ii_in] / - np.clip(src_r['flux'][ri_in], 1.0, None)) - med_ratio = float(np.median(flux_ratio)) - - good = ( - (1.0 - src_r['b'][ri_in] / src_r['a'][ri_in] < ell_max) & - (src_r['flag'][ri_in] == 0) & - (src_r['peak'][ri_in] < sat_level) & - (src_i['peak'][ii_in] < sat_level) & - (np.abs(flux_ratio - med_ratio) < var_thresh * med_ratio) - ) - return ri_orig[ri_in[good]], ii_orig[ii_in[good]] - - -def _build_ref_cores(sub_ref: np.ndarray, src_ref, ri: np.ndarray, - stamp_half: int, core_half: int, bkg_rms: float): - """ - Pre-extract the (2*core_half+1)² PSF core of each selected reference star. - Returns (cores, positions, snr_weights) or (None, None, None) on failure. - positions: list of (x0_stamp, y0_stamp, actual_stamp_half). - """ - H, W = sub_ref.shape - cores, positions, weights = [], [], [] - - for r in ri: - xc = int(round(float(src_ref['x'][r]))) - yc = int(round(float(src_ref['y'][r]))) - sh = stamp_half - while sh >= core_half + 1: - x0 = xc - sh; x1 = xc + sh - y0 = yc - sh; y1 = yc + sh - if x0 >= 0 and y0 >= 0 and x1 < W and y1 < H: - break - sh -= 1 - else: - continue - c0 = sh - core_half; c1 = sh + core_half + 1 - core = sub_ref[y0 + c0: y0 + c1, x0 + c0: x0 + c1].copy() - if core.shape != (c1 - c0, c1 - c0): - continue - snr = float(src_ref['flux'][r]) / (float(src_ref['npix'][r]) * - max(bkg_rms, 1e-6)) - cores.append(core) - positions.append((x0, y0, sh)) - weights.append(max(snr, 0.0) ** 2) - - if not cores: - return None, None, None - return np.array(cores), positions, np.array(weights) - - -def _loss_spline(spline, rows, cols, cores_ref, positions, weights, - dx, dy, core_half) -> float: - shifted = spline(rows - dy, cols - dx) - total = w_sum = 0.0 - for k, (x0, y0, sh) in enumerate(positions): - c0 = sh - core_half; c1 = sh + core_half + 1 - core = shifted[y0 + c0: y0 + c1, x0 + c0: x0 + c1] - if core.shape != cores_ref[k].shape: - continue - diff = core - cores_ref[k] - if not np.all(np.isfinite(diff)): - continue - w = weights[k] - total += w * float(np.mean(diff ** 2)) - w_sum += w - return total / max(w_sum, 1e-30) - - -def _loss_spline_grid(spline, cores_ref, positions, weights, - dy_grid, dx_grid, core_half) -> np.ndarray: - """ - Evaluate the stamp-MSE loss over a full (dy, dx) grid in a single - spline.ev() call instead of one full-image spline evaluation per point. - - Returns a (G, G) float64 array of loss values indexed [i_dy, j_dx]. - """ - G = len(dy_grid) - - # Collect stamp pixel coords and flattened ref values for every star - stamp_rows, stamp_cols, ref_list = [], [], [] - for k, (x0, y0, sh) in enumerate(positions): - c0 = sh - core_half; c1 = sh + core_half + 1 - rs = np.arange(y0 + c0, y0 + c1) - cs = np.arange(x0 + c0, x0 + c1) - rr, cc = np.meshgrid(rs, cs, indexing='ij') - stamp_rows.append(rr.ravel()) - stamp_cols.append(cc.ravel()) - ref_list.append(cores_ref[k].ravel()) - - all_rows = np.concatenate(stamp_rows) # (P,) - all_cols = np.concatenate(stamp_cols) # (P,) - ref_flat = np.concatenate(ref_list) # (P,) - star_sizes = [len(r) for r in stamp_rows] - - # Build shifted pixel coords for every grid point — shape (G*G, P) - DY, DX = np.meshgrid(dy_grid, dx_grid, indexing='ij') - dy_flat = DY.ravel()[:, None] # (G*G, 1) - dx_flat = DX.ravel()[:, None] - - rows_eval = (all_rows[None, :] - dy_flat).ravel() # (G*G*P,) - cols_eval = (all_cols[None, :] - dx_flat).ravel() - - # Single scattered-point spline evaluation for the entire grid - sci = spline.ev(rows_eval, cols_eval).reshape(G * G, -1) # (G*G, P) - - diff2 = (sci - ref_flat[None, :]) ** 2 # (G*G, P) - - # Accumulate weighted MSE per grid point, star by star - total = np.zeros(G * G) - w_sum = np.zeros(G * G) - offset = 0 - for k, sz in enumerate(star_sizes): - sl = slice(offset, offset + sz) - d2 = diff2[:, sl] # (G*G, sz) - fin = np.all(np.isfinite(d2), axis=1) # (G*G,) - total += np.where(fin, weights[k] * d2.mean(axis=1), 0.0) - w_sum += np.where(fin, weights[k], 0.0) - offset += sz - - loss = np.where(w_sum > 0, total / np.maximum(w_sum, 1e-30), np.nan) - return loss.reshape(G, G) - - -def _build_composite(img: np.ndarray, - cores_ref: np.ndarray, - positions: list, - weights: np.ndarray, - core_half: int): - """ - Extract PSF-core stamps from *img* and lay them side by side into a single - composite image of shape (c, N*c) where c = 2*core_half+1. - - The matching reference composite is built the same way from *cores_ref*. - - Returns - ------- - sci_comp : (c, N*c) float64 — stamps from the science frame - ref_comp : (c, N*c) float64 — stamps from the reference cores - w_cols : (N*c,) float64 — per-column SNR² weights (same value per stamp) - """ - c = 2 * core_half + 1 - N = len(positions) - sci_comp = np.empty((c, N * c), dtype=np.float64) - ref_comp = np.empty((c, N * c), dtype=np.float64) - w_cols = np.empty(N * c, dtype=np.float64) - - for k, (x0, y0, sh) in enumerate(positions): - c0 = sh - core_half - c1 = sh + core_half + 1 - sci_stamp = img[y0 + c0: y0 + c1, x0 + c0: x0 + c1] - col_start = k * c - col_end = col_start + c - sci_comp[:, col_start:col_end] = sci_stamp - ref_comp[:, col_start:col_end] = cores_ref[k] - w_cols[col_start:col_end] = weights[k] - - return sci_comp, ref_comp, w_cols - - -def _loss_composite(sci_comp: np.ndarray, - ref_comp: np.ndarray, - w_cols: np.ndarray, - dx: float, dy: float) -> float: - """ - Weighted MSE loss for a (dx, dy) shift evaluated on the composite image, - considering only the central 3×3 pixels of each source stamp. - - *sci_comp* is shifted by (-dy, -dx) — the same rigid shift applied to all - stamps simultaneously — then compared to *ref_comp* at the inner pixels. - - Parameters - ---------- - sci_comp : (c, N*c) science composite from _build_composite - ref_comp : (c, N*c) reference composite from _build_composite - w_cols : (N*c,) per-column SNR² weights - valid_mask : (N*c,) columns that were finite at zero shift - inner_mask : (c, N*c) central 3×3 pixel mask from _build_composite - dx, dy : float sub-pixel shift to test - """ - shifted = nd_shift(sci_comp, (-dy, -dx), order=5, mode='nearest') - diff2 = (shifted - ref_comp) ** 2 - c = sci_comp.shape[0] - N = w_cols.shape[0] // c - ch = (c - 1) // 2 # core_half - r0, r1 = ch - 1, ch + 2 # inner row slice [1:4] - total = w_sum = 0.0 - for k in range(N): - cs = k * c + ch - 1 # inner col start - block = diff2[r0:r1, cs:cs + 3] # (3, 3) - if not np.all(np.isfinite(block)): - continue - w = w_cols[k * c] - total += w * block.sum() - w_sum += w - return total / max(w_sum, 1e-30) - - -def _loss_ndshift(sub_img, cores_ref, positions, weights, - dx, dy, core_half) -> float: - shifted = nd_shift(sub_img, (-dy, -dx), order=5, mode='nearest') - total = w_sum = 0.0 - for k, (x0, y0, sh) in enumerate(positions): - c0 = sh - core_half; c1 = sh + core_half + 1 - core = shifted[y0 + c0: y0 + c1, x0 + c0: x0 + c1] - if core.shape != cores_ref[k].shape: - continue - diff = core - cores_ref[k] - if not np.all(np.isfinite(diff)): - continue - w = weights[k] - total += w * float(np.mean(diff ** 2)) - w_sum += w - return total / max(w_sum, 1e-30) - - -def _per_stamp_uncertainty(sub_img, sub_ref, src_ref, ri, - dx_opt, dy_opt, stamp_half, core_half): - H, W = sub_ref.shape - shifted = nd_shift(sub_img, (-dy_opt, -dx_opt), order=5, mode='nearest') - per_dx, per_dy = [], [] - for r in ri: - xc = int(round(float(src_ref['x'][r]))) - yc = int(round(float(src_ref['y'][r]))) - sh = stamp_half - while sh >= core_half + 1: - x0 = xc - sh; x1 = xc + sh; y0 = yc - sh; y1 = yc + sh - if x0 >= 0 and y0 >= 0 and x1 < W and y1 < H: - break - sh -= 1 - else: - continue - c0 = sh - core_half; c1 = sh + core_half + 1 - cr = sub_ref [y0 + c0: y0 + c1, x0 + c0: x0 + c1] - ci = shifted [y0 + c0: y0 + c1, x0 + c0: x0 + c1] - diff = ci - cr - if not np.all(np.isfinite(diff)): - continue - gx = np.gradient(cr, axis=1); gy = np.gradient(cr, axis=0) - dx2 = float(np.sum(gx ** 2)); dy2 = float(np.sum(gy ** 2)) - if dx2 > 0: per_dx.append(-float(np.sum(diff * gx)) / dx2) - if dy2 > 0: per_dy.append(-float(np.sum(diff * gy)) / dy2) - n = min(len(per_dx), len(per_dy)) - if n > 2: - mad_dx = float(np.median(np.abs(np.array(per_dx) - - np.median(per_dx)))) * 1.4826 - mad_dy = float(np.median(np.abs(np.array(per_dy) - - np.median(per_dy)))) * 1.4826 - return mad_dx / np.sqrt(n), mad_dy / np.sqrt(n) - return np.nan, np.nan - - -def _build_sci_composite(img: np.ndarray, positions: list, core_half: int): - """ - Extract PSF-core stamps from *img* at pre-computed reference positions - and lay them side by side into a (c, N*c) array. - """ - c = 2 * core_half + 1 - N = len(positions) - sci_comp = np.empty((c, N * c), dtype=np.float64) - for k, (x0, y0, sh) in enumerate(positions): - c0 = sh - core_half - c1 = sh + core_half + 1 - sci_comp[:, k * c:(k + 1) * c] = img[y0 + c0: y0 + c1, x0 + c0: x0 + c1] - return sci_comp - - -def _align_fallback_source_pixels(t: int, img: np.ndarray, - ref: np.ndarray, - source_mask: np.ndarray) -> dict: - """ - Fallback alignment matching fit_shift / image_sub behaviour: - shifts the raw science frame (order-5, mode='nearest') to minimise - nansum of squared differences against the source-masked reference, - with a 5-pixel border crop, using Powell with bounds ±3 px. - """ - fail = dict(t=t, dx=0.0, dy=0.0, err_dx=np.nan, err_dy=np.nan, - n_stars=0, converged=False) - try: - if np.nansum(np.abs(img)) == 0: - return fail - - # Build masked template — zeros outside source regions become nan - template = ref.astype(np.float64) * source_mask - template[template == 0] = np.nan - - H = img.shape[0] - crop = 5 if H <= 50 else 10 - - def loss(theta): - row_shift, col_shift = theta - s = nd_shift(img.astype(np.float64), [row_shift, col_shift], - order=5, mode='nearest') - diff = (template - s) ** 2 - return float(np.nansum(diff[crop:-crop, crop:-crop])) - - res = minimize(loss, x0=[0.0, 0.0], method='Powell', - bounds=[(-3.0, 3.0), (-3.0, 3.0)], - options={'xtol': 1e-7, 'ftol': 1e-10, 'maxiter': 5000}) - - row_shift, col_shift = float(res.x[0]), float(res.x[1]) - - # Guard against Powell hitting a bound (indicates failure) - if np.allclose(res.x, [3.0, 3.0]) or np.allclose(res.x, [-3.0, -3.0]): - return fail - - # Convert to sep_aligner dx/dy convention: - # shift(img, [row_shift, col_shift]) aligns science to ref - # _build_shift_array stores arr[t,0]=-dy, arr[t,1]=-dx - # so dy = -row_shift, dx = -col_shift - return dict(t=t, dx=-col_shift, dy=-row_shift, - err_dx=np.nan, err_dy=np.nan, - n_stars=0, converged=True) - except Exception: - return fail - - -def _align_one_frame(t: int, img: np.ndarray, - ref_comp: np.ndarray, - w_cols: np.ndarray, - positions: list, - n_stars: int, - core_half: int, - source_mask: Optional[np.ndarray] = None, - ref: Optional[np.ndarray] = None) -> dict: - """Align one frame. Called by joblib — must be a top-level function. - - Source positions and reference composites are pre-computed once from the - reference frame. Per-frame work is only background subtraction, stamp - extraction at known positions, and Nelder-Mead minimisation. - """ - fail = dict(t=t, dx=0.0, dy=0.0, err_dx=np.nan, err_dy=np.nan, - n_stars=n_stars, converged=False) - try: - img64 = np.ascontiguousarray(img, dtype=np.float64) - bkg = sep.Background(img64) - sub_img = img64 - bkg - - sci_comp = _build_sci_composite(sub_img, positions, core_half) - - fn = lambda p: _loss_composite(sci_comp, ref_comp, w_cols, p[0], p[1]) - res = minimize(fn, x0=[0.0, 0.0], method='Powell', - bounds=[(-3.0, 3.0), (-3.0, 3.0)], - options={'xtol': 1e-7, 'ftol': 1e-10, 'maxiter': 5000}) - dx_opt = float(res.x[0]) - dy_opt = float(res.x[1]) - - return dict(t=t, dx=dx_opt, dy=dy_opt, - err_dx=np.nan, err_dy=np.nan, - n_stars=n_stars, converged=res.success) - except Exception: - if source_mask is not None and ref is not None: - return _align_fallback_source_pixels(t, img, ref, source_mask) - return fail - - -# ───────────────────────────────────────────────────────────────────────────── -# Public class -# ───────────────────────────────────────────────────────────────────────────── - -class SepAligner: - """ - SEP-based sub-pixel image aligner for TESS datacubes. - - Measures the (dx, dy) offset of each frame relative to a reference image - using 3×3 PSF-core stamp minimisation over SEP-selected point sources, - then stores the result in a tessreduce-compatible ``shift`` array. - - Parameters - ---------- - ref : (H, W) ndarray - Reference image (background-subtracted or raw — background is - re-estimated internally per frame). - flux : (T, H, W) ndarray - Datacube of science frames. First axis is time. - n_jobs : int, optional - Number of parallel workers (joblib). -1 = all CPUs. Default -1. - thresh : float, optional - SEP source extraction threshold in units of background σ. Default 3. - sat_frac : float, optional - Sources with peak > sat_frac × global_max are considered saturated. - Default 0.7. - ell_max : float, optional - Maximum ellipticity (1 − b/a) for a source to be used. Default 0.3. - var_thresh : float, optional - Maximum fractional flux change between ref and science frame for a - source to be considered non-variable. Default 0.05. - edge_margin : int, optional - Exclude sources within this many pixels of any image border. - Default 3. Never relaxed even in fallback mode. - coarse_steps : int, optional - Grid points per axis in the coarse offset search. Default 21. - clip_sigma : float, optional - σ threshold for flagging outlier frames in the output DataFrame. - Default 3. - - Attributes - ---------- - shift : (T, 2) ndarray, float32 - Shifts in tessreduce convention: ``shift[t] = [dy, dx]`` such that - ``scipy.ndimage.shift(frame, shift[t])`` moves the frame content to - align with the reference. Zero for failed frames. - offsets : pd.DataFrame - Per-frame measurement table with columns - ``t, dx, dy, err_dx, err_dy, offset, n_stars, converged, sigma_clipped``. - - Examples - -------- - Standalone usage:: - - from sep_aligner import SepAligner - aligner = SepAligner(tr.ref, tr.flux, n_jobs=-1) - aligner.run() - tr.shift = aligner.shift - tr.shift_images() - - Inside tessreduce (add to tessreduce.py reduce() dispatch):: - - elif self._shift_method == 'sep_core': - aligner = SepAligner.from_tessreduce(self) - aligner.run() - """ - - def __init__(self, - ref: np.ndarray, - flux: np.ndarray, - n_jobs: int = -1, - thresh: float = 3.0, - sat_frac: float = 0.7, - ell_max: float = 0.5, - var_thresh: float = 0.05, - edge_margin: int = 3, - coarse_steps: int = 21, - clip_sigma: float = 3.0, - pixel_mask: Optional[np.ndarray] = None, - use_pixel_mask: bool = True, - source_mask: Optional[np.ndarray] = None): - - if flux.ndim != 3: - raise ValueError( - f"flux must be 3-D (T, H, W), got shape {flux.shape}") - if ref.shape != flux.shape[1:]: - raise ValueError( - f"ref shape {ref.shape} must match flux frame shape " - f"{flux.shape[1:]}") - - self.ref = ref - self.flux = flux - self.n_jobs = n_jobs - self.thresh = thresh - self.sat_frac = sat_frac - self.ell_max = ell_max - self.var_thresh = var_thresh - self.edge_margin = edge_margin - self.coarse_steps = coarse_steps - self.clip_sigma = clip_sigma - - # Build a 2-D boolean mask excluding strap (bit 4) and blended source - # (bit 2) pixels from star selection - if use_pixel_mask and pixel_mask is not None: - m = np.asarray(pixel_mask) - if m.ndim == 3: - m = np.any((m & 6) > 0, axis=0) - else: - m = (m & 6) > 0 - self._pixel_mask: Optional[np.ndarray] = m - else: - self._pixel_mask = None - - # 2-D bool source mask (tessreduce bit 1) for fallback alignment - if source_mask is not None: - sm = np.asarray(source_mask) - self._source_mask: Optional[np.ndarray] = ( - sm.any(axis=0) if sm.ndim == 3 else sm.astype(bool)) - else: - self._source_mask = None - - # Outputs — populated by run() - self.shift: Optional[np.ndarray] = None - self.offsets: Optional[pd.DataFrame] = None - - # Pre-compute reference products once - params = _adaptive_params(ref.shape) - self._params = params - self._sub_ref, self._src_ref = _extract( - ref, thresh, params['minarea']) - - # ── Class-method constructor ────────────────────────────────────────────── - - @classmethod - def from_tessreduce(cls, tr, **kwargs) -> 'SepAligner': - """ - Construct from a live tessreduce instance. - - Reads ``tr.ref`` and ``tr.flux``, respects ``tr.parallel`` and - ``tr.num_cores``, and after ``run()`` writes ``tr.shift`` directly. - - Parameters - ---------- - tr : tessreduce instance - **kwargs : forwarded to SepAligner.__init__ (override any default). - """ - n_jobs = tr.num_cores if getattr(tr, 'parallel', True) else 1 - tr_mask = getattr(tr, 'mask', None) - if tr_mask is not None: - _sm = ((tr_mask & 1) == 1).astype(float) - (tr_mask & 2).astype(float) - _sm[_sm <= 0] = 0 - tr_source_mask = _sm.astype(bool) - else: - tr_source_mask = None - inst = cls(ref=np.asarray(tr.ref), - flux=np.asarray(tr.flux), - n_jobs=kwargs.pop('n_jobs', n_jobs), - pixel_mask=kwargs.pop('pixel_mask', tr_mask), - source_mask=kwargs.pop('source_mask', tr_source_mask), - **kwargs) - inst._tr = tr # keep reference so run() can write back - return inst - - # ── Main entry point ────────────────────────────────────────────────────── - - def run(self, time: Optional[np.ndarray] = None, - savgol_window: int = 25, - verbose: int = 0) -> 'SepAligner': - """ - Measure and store offsets for every frame, then smooth with a - Savitzky-Golay filter (order 3) if *time* is provided. - - Parameters - ---------- - time : (T,) array, optional - Observation times in days. If provided, ``savgol_smooth()`` is - called automatically after alignment. - savgol_window : int - Window width passed to ``savgol_smooth()``. Default 25. - verbose : int - joblib verbosity. 0 = silent (default). - - Returns - ------- - self (for method chaining) - """ - T = self.flux.shape[0] - p = self._params - - # Select sources once from the reference frame - ri, _ = _select_stars(self._src_ref, self._src_ref, - self._sub_ref, self._sub_ref, - sat_frac=self.sat_frac, ell_max=self.ell_max, - var_thresh=self.var_thresh, - match_radius=p['match_radius'], - edge_margin=self.edge_margin, - pixel_mask=self._pixel_mask) - - bkg_rms = float(np.std( - self._sub_ref[self._sub_ref < np.percentile(self._sub_ref, 30)])) - bkg_rms = max(bkg_rms, 1e-6) - - cores, positions, weights = _build_ref_cores( - self._sub_ref, self._src_ref, ri, - p['stamp_half'], p['core_half'], bkg_rms) - - if cores is None or len(cores) < 2: - raise RuntimeError('[SepAligner] fewer than 2 usable sources in reference frame') - - print(f'[SepAligner] {len(cores)} sources selected for alignment') - - _, ref_comp, w_cols = _build_composite( - self._sub_ref, cores, positions, np.asarray(weights), p['core_half']) - - results = Parallel(n_jobs=self.n_jobs, verbose=verbose, - backend='loky')( - delayed(_align_one_frame)( - t, self.flux[t], - ref_comp, w_cols, - positions, len(cores), p['core_half'], - self._source_mask, self.ref) - for t in range(T)) - - results.sort(key=lambda r: r['t']) - - n_fallback = sum(1 for r in results if r['converged'] and r['n_stars'] == 0) - if n_fallback > 0: - print(f"!!!WARNING!!! {n_fallback} frame(s) had fewer than 10 sources — " - f"source-pixel alignment used as fallback.") - - self.offsets = self._build_offsets_df(results) - self.shift = self._build_shift_array(results, T) - - if time is not None: - self.smooth_shift(time, method='savgol', savgol_window=savgol_window, - update_shift=True) - - # Write back to tessreduce instance if constructed via from_tessreduce - if hasattr(self, '_tr'): - self._tr.shift = self.shift - if getattr(self._tr, 'diagnostic_plot', False): - savename = getattr(self._tr, 'savename', None) - self.plot_source_selection(savename=savename) - self.plot_source_quality(savename=savename) - - return self - - # ── Output builders ─────────────────────────────────────────────────────── - - def _build_offsets_df(self, results: list) -> pd.DataFrame: - rows = [dict( - t = r['t'], - dx = r['dx'], - dy = r['dy'], - err_dx = r['err_dx'], - err_dy = r['err_dy'], - offset = float(np.hypot(r['dx'], r['dy'])) - if r['converged'] else np.nan, - n_stars = r['n_stars'], - converged = r['converged'], - ) for r in results] - df = pd.DataFrame(rows) - - # Flag outlier frames across the time axis - ok = df['converged'] - df['sigma_clipped'] = False - if ok.sum() > 3: - for col in ('dx', 'dy'): - vals = df.loc[ok, col].values - med = float(np.median(vals)) - mad = float(np.median(np.abs(vals - med))) * 1.4826 - df.loc[ok, 'sigma_clipped'] |= ( - np.abs(vals - med) > self.clip_sigma * mad) - return df - - def _build_shift_array(self, results: list, T: int) -> np.ndarray: - """ - Build (T, 2) float32 shift array in tessreduce convention. - - tessreduce.shift_images() does: - shifted[i] = ndimage.shift(frame, [shift[i,0], shift[i,1]]) - where positive shift[i,0] moves content DOWN (row increases). - - Our dx, dy are defined as (x_science − x_ref), (y_science − y_ref). - To bring science into alignment with ref we need to apply (−dx, −dy). - In scipy row-major convention that is shift=(−dy, −dx). - So: shift[t, 0] = −dy (row shift) - shift[t, 1] = −dx (col shift) - """ - arr = np.zeros((T, 2), dtype=np.float32) - for r in results: - t = r['t'] - if r['converged']: - arr[t, 0] = -r['dy'] # row shift = −dy - arr[t, 1] = -r['dx'] # col shift = −dx - return arr - - # ── Convenience properties ──────────────────────────────────────────────── - - @property - def dx(self) -> Optional[np.ndarray]: - """Measured x-offsets (science − ref) in pixels, shape (T,).""" - return (None if self.offsets is None - else self.offsets['dx'].to_numpy()) - - @property - def dy(self) -> Optional[np.ndarray]: - """Measured y-offsets (science − ref) in pixels, shape (T,).""" - return (None if self.offsets is None - else self.offsets['dy'].to_numpy()) - - @property - def n_stars(self) -> Optional[np.ndarray]: - """Number of stars used per frame, shape (T,).""" - return (None if self.offsets is None - else self.offsets['n_stars'].to_numpy()) - - # ── Time-smoothed shifts ────────────────────────────────────────────────── - - def savgol_smooth(self, - time: np.ndarray, - window: int = 25, - gap_thresh: float = 0.5, - update_shift: bool = True, - plot: Optional[bool] = None, - savename: Optional[str] = None, - ) -> np.ndarray: - """ - Smooth measured shifts with a 3rd-order Savitzky-Golay filter, - applied independently within each observing segment. - - Parameters - ---------- - time : (T,) array - Observation times in days. - window : int - Filter window width in frames. Must be odd and > 3; even values - are incremented by 1. Default 25. - gap_thresh : float - Cadence gap in days that marks a segment break. Default 0.5. - update_shift : bool - If True (default), overwrite ``self.shift`` with the smoothed - values. - plot : bool, optional - Show diagnostic plot. If None, reads ``self._tr.diagnostic_plot`` - when constructed via ``from_tessreduce()``. - savename : str, optional - If provided, save the plot as ``_disp_corr.pdf``. - - Returns - ------- - smoothed : (T, 2) float32 ndarray - """ - from scipy.signal import savgol_filter as _savgol - - if self.shift is None: - raise RuntimeError("Call run() before savgol_smooth().") - - T = len(self.shift) - t_arr = np.asarray(time, dtype=np.float64) - - win = int(window) - if win % 2 == 0: - win += 1 - - diffs = np.diff(t_arr) - gap_idx = np.where(diffs > gap_thresh)[0] - seg_starts = np.concatenate([[0], gap_idx + 1]) - seg_ends = np.concatenate([gap_idx, [T - 1]]) - segments = [np.arange(s, e + 1) - for s, e in zip(seg_starts, seg_ends)] - - raw = self.shift.astype(np.float64).copy() - smoothed = raw.copy() - - for seg_idx in segments: - n = len(seg_idx) - if n < 4: - continue - w = min(win, n if n % 2 == 1 else n - 1) - for axis in range(2): - smoothed[seg_idx, axis] = _savgol( - raw[seg_idx, axis], window_length=w, polyorder=3) - - smoothed = smoothed.astype(np.float32) - if update_shift: - self.shift = smoothed - if hasattr(self, '_tr'): - self._tr.shift = smoothed - - if plot is None: - plot = getattr(getattr(self, '_tr', None), 'diagnostic_plot', False) - if plot: - self._plot_shifts(t_arr, raw, smoothed, gap_thresh, savename) - - return smoothed - - def smooth_shift(self, - time: np.ndarray, - method: str = 'savgol', - gap_thresh: float = 0.5, - length_scale: Optional[float] = None, - sigma_clip: float = 4.0, - sigma_clip_shifts: bool = False, - adaptive: bool = True, - adaptive_range: float = 3.0, - median_filter_width: Optional[int] = 'auto', - savgol_window: int = 25, - update_shift: bool = True, - plot: Optional[bool] = None, - savename: Optional[str] = None, - ) -> np.ndarray: - """ - Return a time-smoothed version of the measured shifts. - - Parameters - ---------- - method : {'savgol', 'gp'} - Smoothing method. ``'savgol'`` (default) applies a 3rd-order - Savitzky-Golay filter with window ``savgol_window``. ``'gp'`` - uses the error-weighted Gaussian-process smoother. - - All other parameters apply only when ``method='gp'``; ``savgol_window`` - applies only when ``method='savgol'``. - - GP smoother: return a time-smoothed version of the measured shifts using a - Gaussian-process-inspired weighted smoother, with automatic gap - detection and error-weighted fitting. - - Data is assumed to be **continuously sampled** within each - observing segment. A segment boundary is declared wherever - consecutive ``time`` values differ by more than ``gap_thresh`` - days (default 0.5 d). Each segment is smoothed independently - so the filter never interpolates across a gap. - - Masked / non-converged frames are **excluded from the fit** but - their smoothed values are filled from the GP prediction evaluated - at their time position, so the returned array is always complete. - - Smoothing kernel - ---------------- - For each output frame *i*, the estimate is an error-weighted - Gaussian kernel average over all *usable* frames *j* in the - same segment:: - - ŝ(tᵢ) = Σⱼ wⱼ · G(tⱼ - tᵢ, ℓ) · sⱼ - ───────────────────────────── - Σⱼ wⱼ · G(tⱼ - tᵢ, ℓ) - - where wⱼ = 1/σⱼ² (from per-stamp measurement errors) and G is - a unit Gaussian with width ℓ (``length_scale``). - - Parameters - ---------- - time : (T,) array of float - Observation times in days (MJD, BJD, …). Must have the - same length as the number of frames T. - gap_thresh : float - Cadence gap in days that marks a segment break. Default 0.5. - length_scale : float, optional - Gaussian smoothing width in days. If None, defaults to - 5 × the median cadence within the first segment (i.e. roughly - 5 frames' worth of smoothing), which is conservative and - appropriate for TESS 2-min or 30-min cadence data. - adaptive : bool - If True (default), dynamically widen the GP kernel where shifts - are stable and contract it where they change rapidly. - adaptive_range : float - Maximum factor by which the length scale can expand or contract - from the base value. ``adaptive_range=3`` means the kernel can - be up to 3× wider or 3× narrower than ``length_scale``. - Default 3.0. - median_filter_width : int or 'auto' or None - Maximum window width (in frames) for the adaptive median post-filter - applied after the GP smooth. ``'auto'`` (default) sets the width - to match the GP length scale converted to frames. ``None`` disables - the filter entirely. Must be odd when specified as int; even values - are incremented by 1. - sigma_clip_shifts : bool - If True, enable outlier rejection before the GP fit. Default False. - sigma_clip : float - Threshold in units of MAD used when ``sigma_clip_shifts=True``. - Frames deviating more than ``sigma_clip`` × MAD from the segment - weighted median are excluded from the fit (but still filled from - the GP). Default 4.0. - update_shift : bool - If True (default), overwrite ``self.shift`` with the smoothed - values so a subsequent ``apply()`` or - ``tessreduce.shift_images()`` uses them. - plot : bool, optional - Whether to show the diagnostic plot. If None (default), reads - ``self._tr.diagnostic_plot`` when constructed via - ``from_tessreduce()``, otherwise defaults to False. - savename : str, optional - If provided, save the plot as ``_disp_corr.pdf`` - matching tessreduce's naming convention. - - Returns - ------- - smoothed : (T, 2) float32 ndarray - Smoothed shifts in tessreduce convention ``[dy, dx]``. - Every frame is populated — masked frames receive the GP - interpolated value. - """ - if method == 'savgol': - return self.savgol_smooth( - time, window=savgol_window, gap_thresh=gap_thresh, - update_shift=update_shift, plot=plot, savename=savename) - - if self.offsets is None: - raise RuntimeError("Call run() before smooth_shift().") - - T = len(self.offsets) - t_arr = np.asarray(time, dtype=np.float64) - if len(t_arr) != T: - raise ValueError( - f"time length {len(t_arr)} must match number of frames {T}") - - # ── Segment detection ───────────────────────────────────────────── - diffs = np.diff(t_arr) - gap_idx = np.where(diffs > gap_thresh)[0] # indices just BEFORE each gap - seg_starts = np.concatenate([[0], gap_idx + 1]) - seg_ends = np.concatenate([gap_idx, [T - 1]]) - segments = [np.arange(s, e + 1) - for s, e in zip(seg_starts, seg_ends)] - - # ── Default length scale ────────────────────────────────────────── - first = segments[0] - if len(first) > 1: - med_cad = float(np.median(np.diff(t_arr[first]))) - else: - med_cad = float(np.median(diffs)) if len(diffs) > 0 else 1.0 - if length_scale is None: - length_scale = 5.0 * med_cad - - # ── Resolve auto median filter width ───────────────────────────── - if median_filter_width == 'auto': - _mfw = max(3, int(round(length_scale / med_cad))) - if _mfw % 2 == 0: - _mfw += 1 - median_filter_width = _mfw - - # ── Per-frame measurement weights (1/σ²) ──────────────────────── - # shift[:,0] = -dy, shift[:,1] = -dx (tessreduce convention) - converged = self.offsets['converged'].to_numpy().astype(bool) - err_dy = self.offsets['err_dy'].to_numpy() - err_dx = self.offsets['err_dx'].to_numpy() - - star_based = converged & np.isfinite(err_dy) & (err_dy > 0) - w_dy = np.where(star_based, 1.0 / err_dy**2, 0.0) - w_dx = np.where(star_based, 1.0 / err_dx**2, 0.0) - - # Fallback frames (converged via source-pixel method) have no error - # estimate — assign them a weight derived from star-based frames so - # they participate in the GP smooth with lower confidence. - fallback = converged & ~star_based - if fallback.any(): - if star_based.any(): - # Use 10% of median star-based weight - med_w_dy = float(np.median(w_dy[star_based])) - med_w_dx = float(np.median(w_dx[star_based])) - else: - # No star-based frames at all — assign uniform unit weight - med_w_dy = 1.0 - med_w_dx = 1.0 - w_dy = np.where(fallback, 0.1 * med_w_dy, w_dy) - w_dx = np.where(fallback, 0.1 * med_w_dx, w_dx) - - # raw shift columns in tessreduce convention - raw = self.shift.astype(np.float64).copy() # (T, 2): [−dy, −dx] - - smoothed = np.full((T, 2), np.nan) - - for seg_idx in segments: - n = len(seg_idx) - if n == 0: - continue - if n == 1: - smoothed[seg_idx] = raw[seg_idx] - continue - - t_seg = t_arr[seg_idx] - - for axis, w_full in enumerate([w_dy, w_dx]): - vals = raw[seg_idx, axis].copy() # e.g. −dy for axis 0 - w_seg = w_full[seg_idx].copy() - - # ── sigma-clip by value within segment ──────────────── - usable = w_seg > 0 - if sigma_clip_shifts and usable.sum() >= 3: - wmed = self._weighted_median(vals[usable], w_seg[usable]) - mad = float(np.median( - np.abs(vals[usable] - wmed))) * 1.4826 - if mad > 0: - outlier = np.abs(vals - wmed) > sigma_clip * mad - w_seg[outlier] = 0.0 # exclude from GP fit - usable = w_seg > 0 - - # ── GP (error-weighted Gaussian kernel) ─────────────── - if adaptive and usable.sum() >= 3: - l_arr = self._adaptive_length_scale( - t_seg, vals, length_scale, adaptive_range) - sm = self._gp_smooth_adaptive( - t_seg, vals, w_seg, usable, l_arr) - else: - sm = self._gp_smooth(t_seg, vals, w_seg, usable, - length_scale) - - # ── adaptive median post-filter ──────────────────────── - if median_filter_width is not None and n >= 3: - mfw_max = int(median_filter_width) - mfw_min = 3 - - grad = np.abs(np.gradient(sm, t_seg)) - grad_sm = np.convolve(grad, np.ones(3) / 3.0, mode='same') - med_g = float(np.median(grad_sm)) - if med_g > 1e-30: - norm = np.clip(grad_sm / (med_g * adaptive_range), 0.0, 1.0) - else: - norm = np.zeros(n) - raw_w = mfw_max - norm * (mfw_max - mfw_min) - win_arr = np.round(raw_w).astype(int) - win_arr += 1 - win_arr % 2 - - filtered = sm.copy() - for i in range(n): - hw = win_arr[i] // 2 - lo = max(0, i - hw) - hi = min(n, i + hw + 1) - filtered[i] = np.median(sm[lo:hi]) - sm = filtered - - smoothed[seg_idx, axis] = sm - - # ── Fallback: any still-NaN positions get nearest-segment-edge ── - for axis in range(2): - col = smoothed[:, axis] - nan_mask = ~np.isfinite(col) - if nan_mask.any(): - good_idx = np.where(~nan_mask)[0] - if len(good_idx): - col[nan_mask] = col[good_idx[ - np.searchsorted(good_idx, - np.where(nan_mask)[0]).clip( - 0, len(good_idx)-1)]] - smoothed[:, axis] = col - - smoothed = smoothed.astype(np.float32) - if update_shift: - self.shift = smoothed - if hasattr(self, '_tr'): - self._tr.shift = smoothed - - # ── Diagnostic plot ─────────────────────────────────────────────── - if plot is None: - plot = getattr(getattr(self, '_tr', None), 'diagnostic_plot', False) - if plot: - self._plot_shifts(t_arr, raw, smoothed, gap_thresh, savename) - - return smoothed - - # ── Diagnostic plot ───────────────────────────────────────────────── - - def _plot_shifts(self, t_arr, raw, smoothed, gap_thresh, savename): - import matplotlib.pyplot as plt - raw_dy = -raw[:, 0].copy() - raw_dx = -raw[:, 1].copy() - sm_dy = -smoothed[:, 0].copy() - sm_dx = -smoothed[:, 1].copy() - gap_idx = np.where(np.diff(t_arr) > gap_thresh)[0] - sm_dy[gap_idx] = np.nan - sm_dx[gap_idx] = np.nan - plt.figure(figsize=(1.5 * fig_width, 1 * fig_width)) - plt.plot(t_arr, raw_dy, '.', label='Row shift', alpha=0.5) - plt.plot(t_arr, raw_dx, '.', label='Col shift', alpha=0.5) - plt.plot(t_arr, sm_dy, '-', label='Smoothed row shift') - plt.plot(t_arr, sm_dx, '-', label='Smoothed col shift') - plt.ylabel('Shift (pixels)', fontsize=15) - plt.xlabel('Time (MJD)', fontsize=15) - plt.legend(fontsize=9) - plt.tight_layout() - if savename is not None: - plt.savefig(savename + '_disp_corr.pdf', bbox_inches='tight') - plt.show() - - def plot_source_selection(self, savename: Optional[str] = None) -> None: - """ - Diagnostic plot showing the reference image with accepted and rejected - SEP sources overlaid, plus stamp/core footprints for accepted sources. - - Green circles — accepted sources used for alignment. - Red circles — detected but rejected sources. - Green squares — stamp region (stamp_half) for each accepted source. - Cyan squares — core region (core_half) used in the MSE loss. - - Parameters - ---------- - savename : str, optional - If provided, save as ``_source_selection.pdf``. - """ - import matplotlib.pyplot as plt - import matplotlib.patches as mpatches - from matplotlib.patches import Rectangle - - sub_ref = self._sub_ref - src_ref = self._src_ref - p = self._params - stamp_half = p['stamp_half'] - core_half = p['core_half'] - - # Re-run star selection on the reference against itself to get - # accepted / rejected index sets (img == ref, so it's self-consistent) - ri_acc, _ = _select_stars( - src_ref, src_ref, sub_ref, sub_ref, - sat_frac=self.sat_frac, ell_max=self.ell_max, - var_thresh=self.var_thresh, - match_radius=self._params['match_radius'], - flag_max=0, - edge_margin=self.edge_margin, - pixel_mask=self._pixel_mask) - - acc_set = set(ri_acc.tolist()) - all_idx = np.arange(len(src_ref)) - rej_idx = np.array([i for i in all_idx if i not in acc_set]) - - fig, ax = plt.subplots(figsize=(1.5 * fig_width, 1.5 * fig_width)) - vmin, vmax = np.nanpercentile(sub_ref, [1, 99]) - ax.imshow(sub_ref, origin='lower', cmap='gray', - vmin=vmin, vmax=vmax, interpolation='nearest') - - # Rejected sources - if len(rej_idx): - ax.scatter(src_ref['x'][rej_idx], src_ref['y'][rej_idx], - s=40, facecolors='none', edgecolors='red', - linewidths=0.8, label='Rejected') - - # Accepted sources + stamp/core boxes - for r in ri_acc: - xc = float(src_ref['x'][r]) - yc = float(src_ref['y'][r]) - ax.scatter(xc, yc, s=40, facecolors='none', - edgecolors='limegreen', linewidths=0.8) - - # Stamp box - sh = stamp_half - ax.add_patch(Rectangle( - (xc - sh - 0.5, yc - sh - 0.5), - 2 * sh + 1, 2 * sh + 1, - linewidth=0.6, edgecolor='limegreen', - facecolor='none', linestyle='--')) - - # Core box - ch = core_half - ax.add_patch(Rectangle( - (xc - ch - 0.5, yc - ch - 0.5), - 2 * ch + 1, 2 * ch + 1, - linewidth=0.6, edgecolor='cyan', - facecolor='none', linestyle='-')) - - # Legend proxies - legend_handles = [ - mpatches.Patch(facecolor='none', edgecolor='limegreen', - label=f'Accepted ({len(ri_acc)})'), - mpatches.Patch(facecolor='none', edgecolor='red', - label=f'Rejected ({len(rej_idx)})'), - mpatches.Patch(facecolor='none', edgecolor='limegreen', - linestyle='--', label='Stamp region'), - mpatches.Patch(facecolor='none', edgecolor='cyan', - label='Core region'), - ] - ax.legend(handles=legend_handles, loc='upper right', fontsize=9, - framealpha=0.7) - H, W = sub_ref.shape - ax.set_xlim(-0.5, W - 0.5) - ax.set_ylim(-0.5, H - 0.5) - ax.set_title('Source selection — reference image', fontsize=11) - ax.set_xlabel('Column (px)', fontsize=15) - ax.set_ylabel('Row (px)', fontsize=15) - plt.tight_layout() - if savename is not None: - plt.savefig(savename + '_source_selection.pdf', bbox_inches='tight') - plt.show() - - def plot_source_quality(self, savename: Optional[str] = None, print_table: bool = False) -> None: - """ - Diagnostic overview of which quality conditions each detected reference - source passes or fails. - - Conditions evaluated (same as _select_stars, self-matched): - 1. In bounds — centre not within edge_margin of any border - 2. Round — ellipticity (1 − b/a) < ell_max - 3. Unflagged — SEP flag == 0 - 4. Unsaturated — peak < sat_frac × global_max - 5. Not masked — centre pixel not flagged by pixel_mask (bit 4) - - Top panel : horizontal bar chart — number of sources passing each - condition (green) and failing (red). - Bottom-left: ellipticity vs normalised peak flux, coloured by - overall pass (green) / fail (red). - Bottom-right: SEP flag value histogram. - - Parameters - ---------- - savename : str, optional - If provided, save as ``_source_quality.pdf``. - """ - import matplotlib.pyplot as plt - - src = self._src_ref - sub = self._sub_ref - H, W = sub.shape - p = self._params - m = self.edge_margin - N = len(src) - - if N == 0: - print('SepAligner: no sources detected in reference — skipping quality plot.') - return - - sat_level = self.sat_frac * float(sub.max()) - - # ── Evaluate each condition per source ──────────────────────────── - in_bounds = ( - (src['x'] >= m) & (src['x'] <= W - 1 - m) & - (src['y'] >= m) & (src['y'] <= H - 1 - m)) - - ell = 1.0 - src['b'] / np.clip(src['a'], 1e-9, None) - is_round = ell < self.ell_max - - is_unflagged = src['flag'] == 0 - is_unsaturated = src['peak'] < sat_level - - if self._pixel_mask is not None: - px = np.clip(np.round(src['x']).astype(int), 0, W - 1) - py = np.clip(np.round(src['y']).astype(int), 0, H - 1) - not_masked = ~self._pixel_mask[py, px] - else: - not_masked = np.ones(N, dtype=bool) - - conditions = { - 'In bounds': in_bounds, - 'Round': is_round, - 'Unflagged': is_unflagged, - 'Unsaturated': is_unsaturated, - 'Not masked': not_masked, - } - - overall_pass = np.ones(N, dtype=bool) - for v in conditions.values(): - overall_pass &= v - - # ── Plot ────────────────────────────────────────────────────────── - fig = plt.figure(figsize=(1.5 * fig_width, 2 * fig_width)) - gs = fig.add_gridspec(2, 2, hspace=0.4, wspace=0.35) - ax_bar = fig.add_subplot(gs[0, :]) - ax_scat = fig.add_subplot(gs[1, 0]) - ax_flag = fig.add_subplot(gs[1, 1]) - - # Bar chart - labels = list(conditions.keys()) - n_pass = [int(v.sum()) for v in conditions.values()] - n_fail = [N - p for p in n_pass] - y = np.arange(len(labels)) - ax_bar.barh(y, n_pass, color='limegreen', label='Pass') - ax_bar.barh(y, n_fail, left=n_pass, color='tomato', label='Fail') - ax_bar.set_yticks(y) - ax_bar.set_yticklabels(labels, fontsize=9) - ax_bar.set_xlabel('Number of sources', fontsize=15) - ax_bar.set_title( - f'Source quality — {N} detected | {int(overall_pass.sum())} pass all', - fontsize=11) - ax_bar.axvline(N, color='k', linewidth=0.5, linestyle='--') - for i, (np_, nf) in enumerate(zip(n_pass, n_fail)): - ax_bar.text(np_ / 2, i, str(np_), va='center', ha='center', - fontsize=7, color='white') - if nf > 0: - ax_bar.text(np_ + nf / 2, i, str(nf), va='center', - ha='center', fontsize=7, color='white') - ax_bar.legend(fontsize=9, loc='lower right') - - # Ellipticity vs peak scatter - peak_norm = src['peak'] / max(float(src['peak'].max()), 1e-9) - colors = np.where(overall_pass, 'limegreen', 'tomato') - ax_scat.scatter(peak_norm, ell, c=colors, s=15, alpha=0.7, - linewidths=0) - ax_scat.axhline(self.ell_max, color='k', linewidth=0.8, - linestyle='--', label=f'ell_max={self.ell_max}') - ax_scat.axvline(self.sat_frac, color='orange', linewidth=0.8, - linestyle='--', label=f'sat_frac={self.sat_frac}') - ax_scat.set_xlabel('Normalised peak flux', fontsize=15) - ax_scat.set_ylabel('Ellipticity (1 − b/a)', fontsize=15) - ax_scat.set_title('Ellipticity vs peak', fontsize=11) - ax_scat.legend(fontsize=9) - - # SEP flag histogram - flag_vals = src['flag'].astype(int) - unique_flags = np.unique(flag_vals) - ax_flag.bar(unique_flags, - [int((flag_vals == f).sum()) for f in unique_flags], - color='steelblue', width=0.6) - ax_flag.set_xlabel('SEP flag value', fontsize=15) - ax_flag.set_ylabel('Count', fontsize=15) - ax_flag.set_title('SEP extraction flags', fontsize=11) - ax_flag.set_xticks(unique_flags) - - plt.tight_layout() - if savename is not None: - plt.savefig(savename + '_source_quality.pdf', bbox_inches='tight') - plt.show() - - # ── Printed table ───────────────────────────────────────────────── - rows = [] - for i in range(N): - rows.append({ - 'ID': i, - 'x (px)': f"{src['x'][i]:.2f}", - 'y (px)': f"{src['y'][i]:.2f}", - 'peak': f"{src['peak'][i]:.1f}", - 'flux': f"{src['flux'][i]:.1f}", - 'In bounds': 'PASS' if bool(in_bounds[i]) else 'FAIL', - 'Round': 'PASS' if bool(is_round[i]) else 'FAIL', - 'Unflagged': 'PASS' if bool(is_unflagged[i]) else 'FAIL', - 'Unsaturated': 'PASS' if bool(is_unsaturated[i])else 'FAIL', - 'Not masked': 'PASS' if bool(not_masked[i]) else 'FAIL', - 'Overall': 'PASS' if bool(overall_pass[i]) else 'FAIL', - }) - table = pd.DataFrame(rows).set_index('ID') - if print_table: - print('\n--- Source quality table ---') - print(table.to_string()) - print(f"\n{int(overall_pass.sum())}/{N} sources pass all conditions\n") - - # ── Smoothing helpers ───────────────────────────────────────────────── - - @staticmethod - def _adaptive_length_scale(t_seg: np.ndarray, vals: np.ndarray, - base_l: float, - adaptive_range: float) -> np.ndarray: - """ - Compute a per-point length scale that widens where shifts are stable - and contracts where they change rapidly. - - The local rate of change is estimated as the magnitude of the gradient - of ``vals`` w.r.t. ``t_seg``, smoothed with a 3-point moving average - to reduce noise sensitivity. The length scale at point i is:: - - ℓ(i) = base_l / max(rate_norm(i), 1 / adaptive_range) - - clipped to [base_l / adaptive_range, base_l * adaptive_range]. - """ - grad = np.abs(np.gradient(vals, t_seg)) - # 3-point moving average to smooth the rate estimate - kernel = np.ones(3) / 3.0 - grad_smooth = np.convolve(grad, kernel, mode='same') - med = float(np.median(grad_smooth)) - if med < 1e-30: - return np.full(len(t_seg), base_l) - rate_norm = grad_smooth / med - l_arr = base_l / np.maximum(rate_norm, 1.0 / adaptive_range) - return np.clip(l_arr, base_l / adaptive_range, base_l * adaptive_range) - - @staticmethod - def _gp_smooth_adaptive(t_seg: np.ndarray, - vals: np.ndarray, - w_seg: np.ndarray, - usable: np.ndarray, - l_arr: np.ndarray) -> np.ndarray: - """ - Non-stationary GP smoother with a per-query-point length scale. - - Each query point i uses its own kernel width ℓ(i) from ``l_arr``:: - - ŝ(i) = Σ_{j∈usable} w_j · exp(-0.5·(tⱼ-tᵢ)²/ℓ(i)²) · vⱼ - ────────────────────────────────────────────────────── - Σ_{j∈usable} w_j · exp(-0.5·(tⱼ-tᵢ)²/ℓ(i)²) - """ - n = len(t_seg) - sm = vals.copy() - - if not usable.any(): - return sm - - t_use = t_seg[usable] - v_use = vals[usable] - w_use = w_seg[usable] - - dt = t_seg[:, None] - t_use[None, :] # (n, n_usable) - G = np.exp(-0.5 * (dt / l_arr[:, None]) ** 2) - WG = w_use[None, :] * G # (n, n_usable) - denom = WG.sum(axis=1) - - valid = denom > 0 - sm[valid] = (WG[valid] @ v_use) / denom[valid] - - if not valid.all(): - t_q = t_seg[~valid] - near = np.argmin(np.abs(t_q[:, None] - t_use[None, :]), axis=1) - sm[~valid] = v_use[near] - - return sm - - @staticmethod - def _weighted_median(vals: np.ndarray, weights: np.ndarray) -> float: - """Weighted median via sorted cumulative weight.""" - idx = np.argsort(vals) - sv = vals[idx]; sw = weights[idx] - cw = np.cumsum(sw) / sw.sum() - return float(np.interp(0.5, cw, sv)) - - @staticmethod - def _gp_smooth(t_seg: np.ndarray, - vals: np.ndarray, - w_seg: np.ndarray, - usable: np.ndarray, - length_scale: float) -> np.ndarray: - """ - Error-weighted Gaussian kernel smoother (vectorised). - - For each query point i, computes:: - - ŝ(i) = Σ_{j∈usable} w_j · G(tⱼ-tᵢ, ℓ) · vⱼ - ───────────────────────────────────── - Σ_{j∈usable} w_j · G(tⱼ-tᵢ, ℓ) - - All query points (including masked frames) are evaluated, so - the output is always fully populated within the segment. - Falls back to the nearest usable value if no usable points - exist within ~3ℓ of the query point. - """ - n = len(t_seg) - sm = np.full(n, np.nan) - - if not usable.any(): - # No usable points — return raw values as-is - return vals.copy() - - t_use = t_seg[usable] - v_use = vals[usable] - w_use = w_seg[usable] - - # Vectorised: (n_query × n_usable) kernel matrix - dt = t_seg[:, None] - t_use[None, :] # (n, n_usable) - G = np.exp(-0.5 * (dt / length_scale) ** 2) - WG = w_use[None, :] * G # (n, n_usable) - denom = WG.sum(axis=1) # (n,) - - valid_query = denom > 0 - sm[valid_query] = (WG[valid_query] @ v_use) / denom[valid_query] - - # Fill any query points with zero kernel weight (very isolated) - # using the nearest usable value - if not valid_query.all(): - t_q = t_seg[~valid_query] - near = np.argmin(np.abs(t_q[:, None] - t_use[None, :]), axis=1) - sm[~valid_query] = v_use[near] - - return sm - - # ── Apply alignment to an arbitrary cube ───────────────────────────────── - - def apply(self, cube: Optional[np.ndarray] = None, - order: int = 3) -> np.ndarray: - """ - Apply the measured shifts to a cube and return the aligned result. - - Parameters - ---------- - cube : (T, H, W) ndarray, optional - Cube to align. Defaults to ``self.flux``. - order : int - Spline interpolation order (default 3). - - Returns - ------- - aligned : (T, H, W) float32 ndarray - """ - if self.shift is None: - raise RuntimeError("Call run() before apply().") - if cube is None: - cube = self.flux - T = cube.shape[0] - out = np.full_like(cube, np.nan, dtype=np.float32) - for t in range(T): - out[t] = nd_shift(cube[t].astype(np.float64), - [self.shift[t, 0], self.shift[t, 1]], - order=order, mode='constant', - cval=np.nan).astype(np.float32) - return out - - # ── Repr ────────────────────────────────────────────────────────────────── - - def __repr__(self) -> str: - status = 'not run' if self.shift is None else ( - f"{int((self.offsets['converged']).sum())}" - f"/{len(self.offsets)} frames converged") - return (f"SepAligner(shape={self.flux.shape}, " - f"n_jobs={self.n_jobs}, status={status})") diff --git a/tessreduce/sigmacut.py b/tessreduce/sigmacut.py index 9a4f801..eef4e9c 100755 --- a/tessreduce/sigmacut.py +++ b/tessreduce/sigmacut.py @@ -228,7 +228,7 @@ def calcaverage_sigmacut(self,data,mask=None,mean=None,stdev=None,Nsigma=None,fi else: self.mean_err = None self.mean = None - self.stdev_err = None + self.stdev_err = None self.stdev = None self.Nskipped = 0 return(1) diff --git a/tessreduce/tessreduce.py b/tessreduce/tessreduce.py index 2246b25..c0f24fc 100644 --- a/tessreduce/tessreduce.py +++ b/tessreduce/tessreduce.py @@ -3,11 +3,13 @@ """ import traceback import os -import time import pandas as pd +import matplotlib.pyplot as plt import numpy as np import lightkurve as lk +from photutils.detection import StarFinder +from PRF import TESS_PRF from copy import deepcopy @@ -16,16 +18,24 @@ from scipy.signal import savgol_filter +from scipy.interpolate import interp1d + from astropy.stats import sigma_clipped_stats from astropy.stats import sigma_clip +from astropy.coordinates import SkyCoord +from astropy import units as u +from astropy.time import Time import multiprocessing from joblib import Parallel, delayed +from tqdm import tqdm from .catalog_tools import * from .calibration_tools import * from .ground_tools import ground +from .rescale_straps import correct_straps from .lastpercent import * +from .psf_photom import create_psf from .helpers import * from .cat_mask import Cat_mask @@ -34,94 +44,28 @@ # nuke warnings because sigma clip is extremely annoying warnings.filterwarnings("ignore") warnings.filterwarnings("ignore", category=RuntimeWarning) -_visible_dep_warning = getattr(getattr(np, 'exceptions', np), 'VisibleDeprecationWarning', None) -if _visible_dep_warning is not None: - warnings.filterwarnings("ignore", category=_visible_dep_warning) +warnings.filterwarnings("ignore", category=np.VisibleDeprecationWarning) pd.options.mode.chained_assignment = None +with warnings.catch_warnings(): + warnings.simplefilter("ignore") + sigma_clip + sigma_clipped_stats # set the package directory so we can load in a file later package_directory = os.path.dirname(os.path.abspath(__file__)) + '/' fig_width_pt = 240.0 # Get this from LaTeX using \showthe\columnwidth -inches_per_pt = 1.0/72.27 # Convert pt to inches +inches_per_pt = 1.0/72.27 # Convert pt to inches golden_mean = (np.sqrt(5)-1.0)/2.0 # Aesthetic ratio fig_width = fig_width_pt*inches_per_pt # width in inches -def _subtract_residual_surface(bkg, flux, bkgmask, box_size=20, filter_size=5, sigma=3.0): - """ - Fit and subtract a smooth 2D residual surface per frame using photutils - Background2D. Operates on (flux - bkg) to capture large-scale structure - missed by the primary background estimation. - - Parameters - ---------- - bkg : np.ndarray (T, X, Y) - Current background estimate; updated in-place. - flux : np.ndarray (T, X, Y) - Raw flux cube. - bkgmask : np.ndarray (X, Y) or (T, X, Y) - Background mask as produced by the background function: NaN where - pixels are excluded (sources/straps), 1.0 where valid background. - If 3D, a pixel is excluded if it is NaN in any frame. - box_size : int - Side length of the background mesh boxes in pixels. - filter_size : int - Size of the median filter applied to the mesh before interpolation. - sigma : float - Sigma threshold for iterative sigma-clipping within each box. - - Returns - ------- - bkg : np.ndarray (T, X, Y) - Background cube with the per-frame 2D surface added. - """ - from photutils.background import Background2D, MedianBackground - from astropy.stats import SigmaClip - from joblib import Parallel, delayed - - sc = SigmaClip(sigma=sigma, maxiters=5) - estimator = MedianBackground() - - bkgmask = np.asarray(bkgmask) - if bkgmask.ndim == 3: - exclude_mask = np.any(np.isnan(bkgmask), axis=0) - else: - exclude_mask = np.isnan(bkgmask) - - def _fit_frame(residual): - finite_vals = residual[~exclude_mask & np.isfinite(residual)] - med = np.nanmedian(finite_vals) - std = np.nanstd(finite_vals) - transient_mask = exclude_mask | (residual > med + 5 * std) - try: - b = Background2D(residual, - box_size=box_size, - filter_size=filter_size, - sigma_clip=sc, - bkg_estimator=estimator, - mask=transient_mask, - fill_value=0.0) - return b.background - except Exception: - return np.full_like(residual, np.nanmedian(residual[~transient_mask])) - - n_jobs = -1 - residuals = flux - bkg - corrections = Parallel(n_jobs=n_jobs)(delayed(_fit_frame)(residuals[i]) for i in range(flux.shape[0])) - bkg += np.array(corrections) - - return bkg - - class tessreduce(): def __init__(self,ra=None,dec=None,name=None,obs_list=None,tpf=None,size=90,sector=None, - reduce=True,align=True,diff=True,corr_correction=False,kernel_match=False,calibrate=True,sourcehunt=True, + reduce=True,align=True,diff=True,corr_correction=True,calibrate=True,sourcehunt=True, phot_method='aperture',imaging=False,parallel=True,num_cores=-1,diagnostic_plot=False,plot=True, - savename=None,quality_bitmask='hard',cache_dir=None,cache=True,catalogue_path=False, - shift_method='sep_core',use_error_image=False,prf_path=None,verbose=1,col_offset=0, - bkg_temporal_window=501,ref_ind=None,ref_type='stack',ref_time_window=2,vector_path=None, - smooth_motion=False,orbit_ref=False,bkg_gauss_sigma=4,create_lc=True,center_mask=True,timing=False): + savename=None,quality_bitmask='default',cache_dir=None,catalogue_path=False, + prf_path=None,verbose=1): """ Class for extracting reduced TESS photometry around a target coordinate or event. @@ -181,8 +125,6 @@ def __init__(self,ra=None,dec=None,name=None,obs_list=None,tpf=None,size=90,sect Path to local TESS PRF files. The default is currently a specific location on the OzStar supercomputer. verbose : int, optional Controls the level of verbosity, 0 is none, 1 is verbose. The default is 1. - timing : bool, optional - Print execution time reports for major pipeline blocks in background() and reduce(). The default is False. """ @@ -195,34 +137,19 @@ def __init__(self,ra=None,dec=None,name=None,obs_list=None,tpf=None,size=90,sect self.tpf = tpf # Reduction Process Specific - self._create_lc = create_lc self.align = align self.calibrate = calibrate self.corr_correction = corr_correction self.diff = diff - self.kernel_match = kernel_match - self.orbit_ref = orbit_ref - self._bkg_gauss_sigma = bkg_gauss_sigma - self._center_mask = center_mask self.imaging = imaging self.parallel = parallel - self._col_offset = col_offset - if isinstance(num_cores, str): + if type(num_cores) == str: self.num_cores = multiprocessing.cpu_count() else: self.num_cores = num_cores self._assign_phot_method(phot_method) self._sourcehunt = sourcehunt self.verbose = verbose - self._shift_method = shift_method - self._use_error_image = use_error_image - self._bkg_temporal_window = bkg_temporal_window - self._force_ref_ind = ref_ind - self._ref_type = ref_type - self._ref_time_window = ref_time_window - self._quality_bitmask = quality_bitmask - self._smooth_motion = smooth_motion - self._timing = timing # Offline Paths if catalogue_path is None: @@ -233,7 +160,6 @@ def __init__(self,ra=None,dec=None,name=None,obs_list=None,tpf=None,size=90,sect self.num_cores = num_cores self.imaging = imaging self._prf_path = prf_path - self._vector_path = vector_path # Plotting self.plot = plot @@ -242,11 +168,9 @@ def __init__(self,ra=None,dec=None,name=None,obs_list=None,tpf=None,size=90,sect # Calculated self.mask = None - #self._over_sub = None self.shift = None self.bkg = None self.flux = None - self.delta_kernel = None self.ref = None self.ref_ind = None self.wcs = None @@ -258,7 +182,6 @@ def __init__(self,ra=None,dec=None,name=None,obs_list=None,tpf=None,size=90,sect self.zp_e = None self.sn_name = None self.ebv = 0 - self.epsf = None # repeat for backup self.tzp = None self.tzp_e = None @@ -279,48 +202,36 @@ def __init__(self,ra=None,dec=None,name=None,obs_list=None,tpf=None,size=90,sect self.ra = obs_list['RA'].to_numpy()[0] self.dec = obs_list['DEC'].to_numpy()[0] self.sector = obs_list['Sector'].to_numpy() + if isinstance(obs_list,list): + obs_list = np.array(obs_list,dtype=object) + if len(obs_list.shape) > 1: + obs_list = obs_list[obs_list[:,3].astype('bool')][0] + self.ra = obs_list[0] + self.dec = obs_list[1] + self.sector = obs_list[2] + elif isinstance(obs_list, pd.DataFrame): + self.ra = obs_list['RA'].to_numpy()[0] + self.dec = obs_list['DEC'].to_numpy()[0] + self.sector = obs_list['Sector'].to_numpy() # Generate coordinate information from 'tpf' if tpf is not None: - if isinstance(tpf, str): - self.tpf = lk.TessTargetPixelFile(tpf,quality_bitmask=self._quality_bitmask) + if type(tpf) == str: + self.tpf = lk.TessTargetPixelFile(tpf) self.flux = strip_units(self.tpf.flux) - if self._use_error_image: - self.eflux = strip_units(self.tpf.flux_err) - else: - self.eflux = None - self.flux[np.isnan(self.flux)] = 0 - self.mjd = self.tpf.time.mjd self.wcs = self.tpf.wcs self.ra = self.tpf.ra self.dec = self.tpf.dec self.size = self.tpf.flux.shape[1] - if self.tpf.sector is not None: - self.sector = self.tpf.sector - if not self.sector: - # Try FITS header directly (tessellate files leave SECTOR blank) - try: - s = self.tpf.hdu[0].header.get('SECTOR') - if s: - self.sector = int(s) - except Exception: - pass - if not self.sector: - # Parse from filename: sector27_... or s0027... - import re - m = re.search(r'sector(\d+)', str(tpf), re.IGNORECASE) - if not m: - m = re.search(r's(\d{4})', str(tpf)) - if m: - self.sector = int(m.group(1)) - if not self.sector: - self.sector = 999 + self.sector = self.tpf.sector + if self.sector is None: + self.sector = 30 # Retrieve TPF elif self.check_coord(): if self.verbose>0: - print('Downloading TPF from TESScut') - self.get_TESS(quality_bitmask=self._quality_bitmask,cache_dir=cache_dir,cache=cache) + print('getting TPF from TESScut') + self.get_TESS(quality_bitmask=quality_bitmask,cache_dir=cache_dir) self._get_gaia() self.ground = ground(ra = self.ra, dec = self.dec) @@ -338,7 +249,7 @@ def check_coord(self): """ - if ((self.ra is None) or (self.dec is None)) and (self.name is None): + if ((self.ra is None) | (self.dec is None)) & (self.name is None): return False else: return True @@ -363,9 +274,9 @@ def _get_gaia(self,maglim=21): result = Get_Catalogue(self.tpf, Catalog = 'gaia') result = result[result.Gmag < maglim] result = result.rename(columns={'RA_ICRS': 'ra', - 'DE_ICRS': 'dec', - 'e_RA_ICRS': 'e_ra', - 'e_DE_ICRS': 'e_dec',}) + 'DE_ICRS': 'dec', + 'e_RA_ICRS': 'e_ra', + 'e_DE_ICRS': 'e_dec',}) # Convert star RA/DEC to pixel values and input into dataframe x,y = self.wcs.all_world2pix(result['ra'].values,result['dec'].values,0) @@ -374,7 +285,7 @@ def _get_gaia(self,maglim=21): # Restrict catalogue to only objects inside cutout ind = (((x > 0) & (y > 0)) & ((x < (self.flux.shape[2])) & (y < (self.flux.shape[1])))) - result = result[ind] + result = result.iloc[ind] self.gaia = result @@ -399,7 +310,7 @@ def _assign_phot_method(self,phot_method): """ - if isinstance(phot_method, str): + if type(phot_method) == str: method = phot_method.lower() if (method == 'psf') | (method == 'aperture'): self.phot_method = method @@ -407,16 +318,10 @@ def _assign_phot_method(self,phot_method): m = f'The input method "{method}" is not supported, please select either "psf", or "aperture".' raise ValueError(m) else: - m = 'phot_method must be a string equal to either "psf", or "aperture".' + m = 'phot_mehtod must be a string equal to either "psf", or "aperture".' raise ValueError(m) - def __clean_lk_cache(self,cache_dir=None): - if cache_dir is None: - cache = lk.config.get_cache_dir() - - - def get_TESS(self,ra=None,dec=None,name=None,size=None,sector=None, - quality_bitmask='default',cache_dir=None,cache=True): + def get_TESS(self,ra=None,dec=None,name=None,size=None,sector=None,quality_bitmask='default',cache_dir=None): """ Use the lightcurve interface with TESScut to get an FFI cutout of a region around the given coords. @@ -454,9 +359,6 @@ def get_TESS(self,ra=None,dec=None,name=None,size=None,sector=None, """ - from astropy.coordinates import SkyCoord - from astropy import units as u - if sector is None: sector = self.sector @@ -476,28 +378,15 @@ def get_TESS(self,ra=None,dec=None,name=None,size=None,sector=None, # Download tpf = tess.download(quality_bitmask=quality_bitmask,cutout_size=size,download_dir=cache_dir) - if not cache: - try: - os.remove(tpf.path) - if self.verbose > 0: - print('Cache removed') - except OSError: - print(f'Failed to remove: {tpf.path}') # Check to ensure it succeeded if tpf is None: m = 'Failure in TESScut api, not sure why.' raise ValueError(m) - self.tpf = tpf + self.tpf = tpf self.flux = strip_units(tpf.flux) # Stripping astropy units so only numbers are returned - self.flux[np.isnan(self.flux)] = 0 - if self._use_error_image: - self.eflux = strip_units(tpf.flux_err) - else: - self.eflux = None - self.wcs = tpf.wcs - self.mjd = tpf.time.mjd + self.wcs = tpf.wcs def make_mask(self,catalogue_path=None,maglim=19,scale=1,strapsize=6,useref=False): """ @@ -529,7 +418,6 @@ def make_mask(self,catalogue_path=None,maglim=19,scale=1,strapsize=6,useref=Fals 2 - saturated source 4 - strap mask 8 - bad pixel (not used) - 8 - data-driven source (from residual background mask) """ @@ -537,40 +425,38 @@ def make_mask(self,catalogue_path=None,maglim=19,scale=1,strapsize=6,useref=Fals # Generate mask from source catalogue if useref: - mask, cat = Cat_mask(self.tpf,catalogue_path,maglim,scale,strapsize,ref=self.ref,col_offset=self._col_offset) + mask, cat = Cat_mask(self.tpf,catalogue_path,maglim,scale,strapsize,ref=self.ref) else: - mask, cat = Cat_mask(self.tpf,catalogue_path,maglim,scale,strapsize,col_offset=self._col_offset) + mask, cat = Cat_mask(self.tpf,catalogue_path,maglim,scale,strapsize) # Generate sky background as the inverse of mask - sky = ((mask & 1)+1 == 1) * 1. + sky = ((mask & 1)+1 ==1) * 1. sky[sky==0] = np.nan tmp = np.nansum(data*sky,axis=(1,2)) tmp[tmp==0] = 1e12 # random big number ref = data[np.argmin(tmp)] * sky - ## Old code, no longer used - ## Compute a spatial QE map from a single reference frame. - ## Stored as self.qe_spatial for diagnostic use; the temporal QE - ## correction applied during background() is computed separately by _calc_qe. - # try: - # self.qe_spatial = correct_straps(ref,mask,parallel=True) - # except: - # self.qe_spatial = correct_straps(ref,mask,parallel=False) - + # Correct for the electrical straps + try: + qe = correct_straps(ref,mask,parallel=True) + except: + qe = correct_straps(ref,mask,parallel=False) + c1 = data.shape[1] // 2 c2 = data.shape[2] // 2 cmask = np.zeros_like(data[0],dtype=int) - if self._center_mask: - cmask[c1-1:c1+2, c2-1:c2+2] = 1 + cmask[c1,c2] = 1 + kern = np.ones((5,5)) + cmask = convolve(cmask,kern) fullmask = mask | cmask - sky = ((fullmask & 1)+1 == 1) * 1. + sky = ((fullmask & 1)+1 ==1) * 1. sky[sky==0] = np.nan - masked = np.abs(ref*sky) + masked = ref*sky mean,med,std = sigma_clipped_stats(masked)# assume sources weight the mean above the bkg if useref is False: - m_second = (masked - mean > 2*std).astype(int) + m_second = (masked > mean+2*std).astype(int) self.mask = fullmask | m_second else: self.mask = fullmask @@ -597,37 +483,21 @@ def psf_source_mask(self,sigma=5): """ - from PRF import TESS_PRF - - col = self.tpf.column + int(self.size//2) # find column and row, when specifying location on a *say* 90x90 px cutout - row = self.tpf.row + int(self.size//2) - - col += 45 # add on the non-science columns - row += 1 # add on the non-science row - if col > 2090: - col = 2090 - if row > 2040: - row = 2040 - # Find PRF for cutout (depends on Sector, Camera, CCD, Pixel Row, Pixel Column) if self._catalogue_path is not None: if self.sector < 4: prf = TESS_PRF(self.tpf.camera,self.tpf.ccd,self.sector, - col,row, + self.tpf.column+self.flux.shape[2]/2,self.tpf.row+self.flux.shape[1]/2, localdatadir=f'{self._prf_path}/Sectors1_2_3') else: prf = TESS_PRF(self.tpf.camera,self.tpf.ccd,self.sector, - col,row, + self.tpf.column+self.flux.shape[2]/2,self.tpf.row+self.flux.shape[1]/2, localdatadir=f'{self._prf_path}/Sectors4+') else: - try: - prf = TESS_PRF(self.tpf.camera,self.tpf.ccd,self.sector, - col,row) - except Exception as e: - print(f'Warning: could not load PRF (network error?): {e}') - return np.ones((self.flux.shape[0], self.flux.shape[1], self.flux.shape[2])) - + prf = TESS_PRF(self.tpf.camera,self.tpf.ccd,self.sector, + self.tpf.column+self.flux.shape[2]/2,self.tpf.row+self.flux.shape[1]/2) + self.prf = prf.locate(5,5,(11,11)) # Iterate through frames to find PRF like sources @@ -648,41 +518,7 @@ def psf_source_mask(self,sigma=5): m[i] = par_psf_source_mask(data[i],self.prf,sigma) return m * 1.0 - def _calc_qe(self):#,flux_e): - ''' - Calculate the effective quantum efficiency enhancement of the detector from scattered light. - ''' - time = deepcopy(self.mjd) - strap_data = (self.flux) * ((self.mask&4) > 0)*(~self.mask&1) - qe = strap_data/self.bkg - qe[qe == 0] = np.nan - m,med,std = sigma_clipped_stats(qe,axis=1,sigma_upper=2) - qes = np.ones_like(qe) - qes[:,:,:] = med[:,np.newaxis,:] - qes[np.isnan(qes)] = 1 - - av_bkg = np.sum(self.bkg,axis=(1,2))/(self.bkg.shape[1]*self.bkg.shape[2]) - m,med,std = sigma_clipped_stats(av_bkg) - ind = av_bkg < med + 5*std - breaks = np.where(np.diff(time[ind]) > 0.5)[0]+1 - breaks = np.insert(breaks, 0, 0) - breaks = np.append(breaks, len(time[ind])) - - new_qes = deepcopy(qes) - ind_where = np.where(ind)[0] - for i in range(len(breaks)-1): - if abs(breaks[i]-breaks[i+1]) > 100: - window_size = int(abs(breaks[i]-breaks[i+1])/4) - if window_size/2 == window_size//2: - window_size += 1 - seg_idx = ind_where[breaks[i]:breaks[i+1]] - sav = savgol_filter(qes[ind][breaks[i]:breaks[i+1]], window_size, 1, axis=0) - new_qes[seg_idx] = sav - new_qes[new_qes < 1.001] = 1 # set a limit of 1% adjustment - self.qe = new_qes - - def background(self,gauss_smooth=None,calc_qe=True,strap_iso=True,source_hunt=False, - interpolate=True,rerun_negative=False,rerun_diff=False,blend_dynamic=False): + def background(self,gauss_smooth=2,calc_qe=True, strap_iso=True,source_hunt=False,interpolate=True): """ Calculate the temporal and spatial variation in the background. @@ -701,46 +537,18 @@ def background(self,gauss_smooth=None,calc_qe=True,strap_iso=True,source_hunt=Fa Using PSF, search for sources in each frame that may not have been masked out by the catalogue source mask. The default is False. interpolate : bool, optional Interpolate over masked out objects when calculating background. The default is True. - + Assigns ------- bkg : np.array Spatially varying background for each frame. """ - _times = {} - _t0_total = time.perf_counter() - if gauss_smooth is None: - gauss_smooth = self._bkg_gauss_sigma - # b = np.nansum(self.flux,axis=(1,2)) - # ind = (b < np.percentile(b,24)) - # if calc_qe: - # m,med,s = sigma_clipped_stats((self.flux)[ind] - self.ref,axis=0) - # else: - # m,med,s = sigma_clipped_stats((self.flux)[ind],axis=0) - # m,med,std = sigma_clipped_stats(s) - - # m = (s > med + 3*std ) * 1. - # if calc_qe: - # m = convolve(m,np.ones((5,5))) - # else: - # m = convolve(m,np.ones((3,3))) - - # m[m>0] = np.nan - # m = abs(m-1) - - # if strap_iso: - # strap_cols = (self.mask & 4) > 0 - # if strap_cols.ndim == 3: - # strap_cols = strap_cols.any(axis=0) - # m[strap_cols] = np.nan - - _t = time.perf_counter() if strap_iso: m = (self.mask == 0) * 1. else: - m = ((self.mask & 1 == 0) & (self.mask & 2 == 0)) * 1. + m = ((self.mask & 1 == 0) & (self.mask & 2 == 0) ) * 1. m[m==0] = np.nan # Find extra sources not found in catalogue mask @@ -749,180 +557,46 @@ def background(self,gauss_smooth=None,calc_qe=True,strap_iso=True,source_hunt=Fa sm[sm==0] = np.nan m = sm * m self._bkgmask = m - _times['mask creation'] = time.perf_counter() - _t # Calculate the smooth background if (self.flux.shape[1] > 30) & (self.flux.shape[2] > 30): - flux = deepcopy(strip_units(self.flux)) - # if calc_qe: - # flux -= self.ref + flux = strip_units(self.flux) bkg_smth = np.zeros_like(flux) * np.nan if self.parallel: - _t = time.perf_counter() - bkg_smth = Parallel(n_jobs=self.num_cores)(delayed(Smooth_bkg)(frame,0,interpolate) for frame in flux*m) - _times['initial smooth background'] = time.perf_counter() - _t - if rerun_negative: - _t = time.perf_counter() - if self._use_error_image: - over_sub = (deepcopy(self.flux) - bkg_smth) < -self.eflux # -0.5 - else: - over_sub = (deepcopy(self.flux) - bkg_smth) < -0.5 - over_sub = np.nansum(over_sub,axis=0) > 0 - #self._over_sub = over_sub - #print('overshape ',over_sub.shape) - #print('m ',m.shape) - strap_mask = (self.mask & 4) > 0 - if len(strap_mask.shape) == 3: - strap_mask = strap_mask[0] - if strap_iso: - over_sub[strap_mask] = 0 - if source_hunt | (len(self.mask.shape) == 3): - m[:,over_sub[:,:]] = 1 - else: - m[over_sub] = 1 - self._bkgmask = m - bkg_smth = Parallel(n_jobs=self.num_cores)(delayed(Smooth_bkg)(frame,gauss_smooth,interpolate) for frame in flux*m) - _times['negative over-subtraction rerun'] = time.perf_counter() - _t - - - if rerun_diff: - _t = time.perf_counter() - from photutils.background import Background2D, MedianBackground - from astropy.stats import SigmaClip - from scipy.ndimage import label - - bkg_smth = np.array(bkg_smth) - mean_bkg = np.nanmean(bkg_smth,axis=(1,2)) - low = bkg_smth[mean_bkg < 300] - fixed_bkg = gaussian_filter(low, sigma=6,axes = 0) - fixed = flux[mean_bkg < 300] - fixed_bkg - # np.save('intermediate_flux.npy',fixed) - # np.save('intermediate_bkg.npy',fixed_bkg) - m,med,std = sigma_clipped_stats(fixed,axis=0) - - estimator = MedianBackground() - sc = SigmaClip(sigma=5, maxiters=5) - b = Background2D(std, - box_size=5, - filter_size=3, - sigma_clip=sc, - bkg_estimator=estimator, - fill_value=0.0) - std_sub = std - b.background - _,smed,sstd = sigma_clipped_stats(std_sub) - resid_mask = (std_sub > smed + 3*sstd) * 1.0 - ny, nx = resid_mask.shape - resid_mask = convolve(resid_mask, np.ones((3, 3))) > 1 - labeled, n_comp = label(resid_mask) - filtered = np.zeros_like(resid_mask) - for comp in range(1, n_comp + 1): - pix = labeled == comp - if pix.sum() > 2000: - continue - filtered[pix] = 1 - filtered[:2, :] = 0 - filtered[-2:, :] = 0 - filtered[:, :2] = 0 - filtered[:, -2:] = 0 - resid_mask = filtered - if source_hunt | (len(self.mask.shape) == 3): - new_mask = deepcopy(sm) - new_mask[:,resid_mask[:,:]] = np.nan - else: - new_mask = deepcopy(resid_mask) * 1.0 - new_mask[new_mask == 1] = np.nan - new_mask = abs(new_mask - 1) - self._bkgmask = new_mask - bkg_s1 = np.array(bkg_smth) - bkg_smth = Parallel(n_jobs=self.num_cores)(delayed(Smooth_bkg)(frame,0,interpolate) for frame in flux*new_mask) - if blend_dynamic: - bkg_smth = blend_dynamic_background(bkg_smth, bkg_s1, flux) - _times['residual surface rerun'] = time.perf_counter() - _t - + bkg_smth = Parallel(n_jobs=self.num_cores)(delayed(Smooth_bkg)(frame,gauss_smooth,interpolate) for frame in flux*m) else: - _t = time.perf_counter() for i in range(flux.shape[0]): - bkg_smth[i] = Smooth_bkg((flux*m)[i],0,interpolate) - _times['initial smooth background'] = time.perf_counter() - _t + bkg_smth[i] = Smooth_bkg((flux*m)[i],gauss_smooth,interpolate) else: print('Small tpf, using percentile cut background') self.small_background() bkg_smth = self.bkg - # Calculate quantum efficiency - self.bkg = np.array(bkg_smth) - _t = time.perf_counter() + # Calculate quantum efficiency if calc_qe: - self._calc_qe()#,self.eflux) - self.bkg *= self.qe - - # if calc_qe: - bkg_pre_fix = np.array(self.bkg) - from .adaptive_background import get_tessvectors, _interpolate_angles - _df = get_tessvectors(self.sector, self.tpf.camera, data_path=self._vector_path) - _bkg_median = np.array([np.nanmedian(self.bkg[i]) for i in range(len(self.bkg))]) - if _df is not None: - _earth_angle, _moon_angle = _interpolate_angles(self.mjd, _df) - _high_bkg_frames = (_earth_angle < 30.0) | (_moon_angle < 30.0) | (_bkg_median > 300.0) + strap = (self.mask == 4) * 1.0 + strap[strap==0] = np.nan + # check if its a time varying mask + if len(strap.shape) == 3: + strap = strap[self.ref_ind] + mask = ((self.mask & 1) == 0) * 1.0 + mask[mask==0] = np.nan + + data = strip_units(self.flux) * mask + norm = self.flux / bkg_smth + straps = norm * ((self.mask & 4)>0) + limit = np.nanpercentile(straps,60,axis=1) + straps[limit[:,np.newaxis,:] < straps] = np.nan + straps[straps==0] = 1 + + value = np.nanmedian(straps,axis=1) + qe = np.ones_like(bkg_smth) * value[:,np.newaxis,:] + bkg = bkg_smth * qe + self.qe = qe else: - _high_bkg_frames = _bkg_median > 300.0 - self.bkg, _sharp_masks, self.bad_bkg = fix_background_anomalies(self.bkg, self.mask, - flux=deepcopy(self.flux), - bkg_prev=bkg_pre_fix if blend_dynamic else None, - bkgmask=self._bkgmask, - gauss_smooth=gauss_smooth, - high_bkg_frames=_high_bkg_frames, - n_jobs=self.num_cores) - _times['anomaly fixing'] = time.perf_counter() - _t - - _t = time.perf_counter() - from .adaptive_background import AdaptiveBackground - smoother = AdaptiveBackground(self.bkg, self.mjd, sector=self.sector, camera=self.tpf.camera, - data_path=self._vector_path,n_jobs=self.num_cores) - if smoother._df is not None: - smoothed = smoother.smooth(method='savgol').smoothed - self.bkg = smoothed - _times['adaptive temporal smoothing'] = time.perf_counter() - _t - - # Store data-driven sources from _bkgmask as bit 8, preserving the catalogue mask (bit 1) - if rerun_diff: - _t = time.perf_counter() - #final correction - f = deepcopy(self.flux) - f -= self.bkg - # m, med, std = sigma_clipped_stats(f - self.bkg, axis=(1, 2)) - bkg2d_mask = np.isnan(np.asarray(self._bkgmask)) - if bkg2d_mask.ndim == 3: - bkg2d_mask = np.any(bkg2d_mask, axis=0) - bkg_corr = parallel_background2d(f, box_size=9, filter_size=3, - sigma=3, maxiters=5, n_jobs=self.num_cores, - mask=bkg2d_mask) - self.bkg += bkg_corr - - bkgmask_arr = np.asarray(self._bkgmask) - if len(self.mask.shape) == 3: - if bkgmask_arr.ndim == 3: - new_sources = np.isnan(bkgmask_arr) - else: - new_sources = np.isnan(bkgmask_arr)[np.newaxis, :, :] - else: - if bkgmask_arr.ndim == 3: - new_sources = np.any(np.isnan(bkgmask_arr), axis=0) - else: - new_sources = np.isnan(bkgmask_arr) - self.mask = self.mask | (new_sources.astype(self.mask.dtype) * 8) - _times['final residual correction'] = time.perf_counter() - _t - - if self._timing: - _total = time.perf_counter() - _t0_total - print('\nBackground timing report:') - for _name, _elapsed in _times.items(): - print(f' {_name:<38s} {_elapsed:6.2f}s ({100*_elapsed/_total:5.1f}%)') - print(f' {"total":<38s} {_total:6.2f}s') - - #self._bkg_temporal_smooth() - #self._bkg_adaptive_smooth() + bkg = np.array(bkg_smth) + self.bkg = bkg def small_background(self): """ @@ -979,9 +653,10 @@ def _bkg_round_3(self,iters=5): dist_mask = convolve(dist_mask,kern) > 0 if self.parallel: bkg_3 = Parallel(n_jobs=self.num_cores)(delayed(parallel_bkg3)(self.bkg[i],dist_mask[i]) - for i in np.arange(len(dist_mask))) + for i in np.arange(len(dist_mask))) else: - bkg_3 = np.zeros_like(self.bkg) + bkg_3 = [] + bkg_smth = np.zeros_like(dist_mask) for i in range(len(dist_mask)): bkg_3[i] = parallel_bkg3(self.bkg[i],dist_mask[i]) self.bkg = np.array(bkg_3) @@ -1003,9 +678,9 @@ def _clip_background(self,sigma=5,ideal_size=90): if self.parallel: bkg_clip = Parallel(n_jobs=self.num_cores)(delayed(clip_background)(self.bkg[i],self.mask,sigma,ideal_size) - for i in np.arange(len(self.bkg))) + for i in np.arange(len(self.bkg))) else: - bkg_clip = np.zeros_like(self.bkg) + bkg_clip = [] for i in range(len(self.bkg)): bkg_clip[i] = clip_background(self.bkg[i],self.mask,ideal_size) self.bkg = np.array(bkg_clip) @@ -1029,234 +704,13 @@ def _grad_bkg_clip(self,sigma=3,max_size=1000): if self.parallel: bkg_clip = Parallel(n_jobs=self.num_cores)(delayed(grad_clip_fill_bkg)(self.bkg[i],sigma,max_size) - for i in np.arange(len(self.bkg))) + for i in np.arange(len(self.bkg))) else: - bkg_clip = np.zeros_like(self.bkg) + bkg_clip = [] for i in range(len(self.bkg)): bkg_clip[i] = grad_clip_fill_bkg(self.bkg[i],max_size) self.bkg = np.array(bkg_clip) - def _bkg_temporal_smooth(self,window_size=None): - if window_size is None: - window_size = self._bkg_temporal_window # still need to decide what this is - - #grad = np.gradient(np.sum(self.bkg,axis=(1,2)),self.mjd) # not sure about this gradient - av_bkg = np.nanmean(self.bkg,axis=(1,2)) - time = deepcopy(self.mjd) - m,med,std = sigma_clipped_stats(av_bkg) - ind = av_bkg < med + 5*std - # m,med,std = sigma_clipped_stats(abs(grad)) - # ind = abs(grad) < (med + 5*std) - # left = np.concatenate([[False], ind[:-1]]) - # right = np.concatenate([ind[1:], [False]]) - # ind = ind & (left | right) - # from scipy.ndimage import label - # clusters, _ = label(ind) - # sizes = np.bincount(clusters.ravel()) # sizes[i] = number of points in cluster i - # small = sizes < window_size - # ind[small[clusters]] = False - # if np.sum(ind) == 0: - # window_size = int(0.5 * np.max(sizes)) - # if window_size % 2 == 0: - # window_size += 1 - # print(f'!!!WARNING window size for temporal background smoothing decreaesd to {window_size}') - # ind = abs(grad) < (med + 5*std) - # small = sizes < window_size - # ind[small[clusters]] = False - - ind_where = np.where(ind)[0] - - breaks = np.where(np.diff(time[ind]) > 0.5)[0]+1 - breaks = np.insert(breaks, 0, 0) - breaks = np.append(breaks, len(time[ind])) - new_bkg = deepcopy(self.bkg) # shape (T, X, Y) - - for i in range(len(breaks) - 1): - if abs(breaks[i]-breaks[i+1]) > 100: - window_size = int(abs(breaks[i]-breaks[i+1])/4) - if window_size/2 == window_size//2: - window_size += 1 - seg_idx = ind_where[breaks[i]:breaks[i+1]] - seg = new_bkg[seg_idx] # (n_seg, X, Y) - sav = savgol_filter(seg, window_size, 1, axis=0) # (n_seg, X, Y) - - # per-pixel residual threshold - resid = np.abs(seg - sav) # (n_seg, X, Y) - threshold = np.median(resid, axis=0) + 5 * np.std(resid, axis=0) # (X, Y) - - exceeds = resid > threshold[np.newaxis] # (n_seg, X, Y) - - # leading bad run: cumprod stays 1 only while all preceding values were True - start_clip = np.cumprod(exceeds,axis=0).sum(axis=0) # (X, Y) - end_clip = len(seg_idx) - np.cumprod(exceeds[::-1], axis=0).sum(axis=0) - - # use sav only within [start_clip, end_clip), raw outside - t = np.arange(len(seg_idx))[:, np.newaxis, np.newaxis] # (n_seg, 1, 1) - use_sav = (t >= start_clip) & (t < end_clip) - - new_bkg[seg_idx] = np.where(use_sav, sav, seg) - - flux = deepcopy(self.flux) - new_bkg - # med = sigma_clipped_stats(flux,axis=(1,2))[1] - med = np.median(flux.reshape(len(flux), -1), axis=1) - new_bkg += med[:,np.newaxis,np.newaxis] - self.bkg = new_bkg - - - def _bkg_adaptive_smooth(self, gap_thresh=0.5, clip_sigma=5.0, - plot=None, savename=None): - """ - Adaptive temporal Gaussian smoothing of the background cube. - - Two Gaussian filters are computed per segment — one wide (sigma=n/4, - for stable epochs) and one narrow (sigma=n/32, for rapidly varying - epochs) — and linearly blended per-frame based on the local background - gradient estimated from a short first-pass SavGol smooth. - - alpha = 1 → wide filter (stable background, low gradient) - alpha = 0 → narrow filter (variable background, high gradient) - - On simple/stable data (e.g. GRB fields) the gradient is near-zero - everywhere so alpha ≈ 1 and the result matches SavGol n//4. - On complex scattered-light data the gradient is elevated during ramps - so alpha → 0 and the narrower filter tracks the variation. - - Parameters - ---------- - gap_thresh : float - Time gap in days that marks a segment boundary. Default 0.5. - clip_sigma : float - Sigma threshold for outlier frame rejection. Default 5.0. - """ - import matplotlib.pyplot as plt - if plot is None: - plot = self.diagnostic_plot - if savename is None: - savename = self.savename - - av_bkg = np.nanmean(self.bkg, axis=(1, 2)) - av_bkg_raw = av_bkg.copy() - time = deepcopy(self.mjd) - - _, med, std = sigma_clipped_stats(av_bkg) - ind = av_bkg < med + clip_sigma * std - ind_where = np.where(ind)[0] - - breaks = np.where(np.diff(time[ind]) > gap_thresh)[0] + 1 - breaks = np.insert(breaks, 0, 0) - breaks = np.append(breaks, len(time[ind])) - - new_bkg = deepcopy(self.bkg) - alpha_all = np.full(len(time), np.nan) - grad_all = np.full(len(time), np.nan) - - for i in range(len(breaks) - 1): - seg_idx = ind_where[breaks[i]:breaks[i + 1]] - n = len(seg_idx) - if n < 10: - continue - - seg = new_bkg[seg_idx] # (n, X, Y) - av = av_bkg[seg_idx] # (n,) - - # SavGol window sizes — wide for stable regions, narrow for variable. - # SavGol is strictly local (±window/2 frames) so it does not - # average in distant frames the way a Gaussian filter does. - w_wide = max(n // 4, 5) - if w_wide % 2 == 0: - w_wide += 1 - w_narrow = max(n // 8, 5) - if w_narrow % 2 == 0: - w_narrow += 1 - - # ── Pass 1: gradient from short SavGol of spatial mean ─────── - rw = max(min(n // 32, 51), 5) - if rw % 2 == 0: - rw += 1 - av_rough = savgol_filter(av, rw, 1) - grad = np.abs(np.gradient(av_rough)) - gw = max(min(n // 32, 25), 3) - grad_smooth = np.convolve(grad, np.ones(gw) / gw, mode='same') - med_grad = float(np.median(grad_smooth)) - - # ── Blend weight: alpha=1 (wide) where gradient is low ─────── - if med_grad < 1e-10: - alpha = np.ones(n) - else: - rate_norm = grad_smooth / med_grad - alpha = np.clip(1.0 / np.maximum(rate_norm, 1.0), 0.0, 1.0) - - alpha_all[seg_idx] = alpha - grad_all[seg_idx] = grad_smooth - - # ── Pass 2: blend wide and narrow SavGol filters ───────────── - sav_wide = savgol_filter(seg, w_wide, 1, axis=0) - sav_narrow = savgol_filter(seg, w_narrow, 1, axis=0) - a = alpha[:, np.newaxis, np.newaxis] - new_bkg[seg_idx] = a * sav_wide + (1.0 - a) * sav_narrow - - # ── Median flux correction (background pixels only) ────────────── - # Use only source-free pixels so that star/galaxy flux does not - # bias the correction upward. - bkg_pixel_mask = ~(self.mask & 1).astype(bool) # True = background - flux = deepcopy(self.flux) - new_bkg # (T, X, Y) - flux_bkg = flux.copy().astype(float) - flux_bkg[:, ~bkg_pixel_mask] = np.nan - med = np.nanmedian(flux_bkg, axis=(1, 2)) - new_bkg += med[:, np.newaxis, np.newaxis] - self.bkg = new_bkg - - if plot: - av_smooth = np.nanmean(self.bkg, axis=(1, 2)) - t = self.mjd.copy() - - gap_idx = np.where(np.diff(t) > gap_thresh)[0] - def _nan_gaps(arr): - a = arr.copy().astype(float) - if len(gap_idx): - a[gap_idx] = np.nan - return a - - fig, axes = plt.subplots(3, 1, - figsize=(1.5 * fig_width, 3.0 * fig_width), - sharex=True) - - # Panel 1: background + wide / narrow / adaptive smooths - ax = axes[0] - ax.plot(t, av_bkg_raw, '.k', ms=1.5, alpha=0.3, label='Raw') - ax.plot(t, _nan_gaps(av_smooth), lw=1.5, label='Adaptive blend') - ax.set_ylabel('Mean bkg (e⁻/s)', fontsize=11) - ax.legend(fontsize=9) - ax.set_title('Background adaptive Gaussian blend', fontsize=11) - - # Panel 2: gradient and blend weight - ax = axes[1] - col_g = 'C1'; col_a = 'C2' - ax.plot(t, _nan_gaps(grad_all), color=col_g, lw=1, - label='|d(rough bkg)/dt|') - ax.set_ylabel('Gradient (e⁻/s/frame)', fontsize=11, color=col_g) - ax.tick_params(axis='y', labelcolor=col_g) - axr = ax.twinx() - axr.plot(t, _nan_gaps(alpha_all), color=col_a, lw=1, alpha=0.8, - label='α (blend weight)') - axr.set_ylabel('α (1=wide, 0=narrow)', fontsize=11, color=col_a) - axr.tick_params(axis='y', labelcolor=col_a) - axr.set_ylim(-0.05, 1.05) - ax.set_title('High gradient → α→0 (narrow filter)', fontsize=11) - - # Panel 3: residuals - ax = axes[2] - ax.plot(t, _nan_gaps(av_bkg_raw - av_smooth), '.k', ms=1.5, alpha=0.4, - label='Residual (raw − smooth)') - ax.axhline(0, color='r', lw=0.8, ls='--') - ax.set_ylabel('Residual (e⁻/s)', fontsize=11) - ax.set_xlabel('Time (MJD)', fontsize=11) - ax.legend(fontsize=9) - - plt.tight_layout() - plt.show() - if savename is not None: - plt.savefig(savename + '_bkg_smooth.pdf', bbox_inches='tight') def get_ref(self,start = None, stop = None): """ @@ -1280,61 +734,32 @@ def get_ref(self,start = None, stop = None): """ data = strip_units(self.flux) - - if self._force_ref_ind is not None: - self.ref_ind = self._force_ref_ind - self.ref = deepcopy(data[self._force_ref_ind]) - else: - if (start is None) & (stop is None): - start = 0 - stop = len(self.flux) - elif (start is not None) & (stop is None): - stop = len(self.flux) - - elif (start is None) & (stop is not None): - start = 0 - - start = int(start) - stop = int(stop) - - ind = self.tpf.quality[start:stop] == 0 - d = deepcopy(data[start:stop])[ind] - summed = np.nanmedian(d,axis=(1,2)) - summed[summed <=0] = 1e5 - lim = np.argmin(summed) - lim = np.percentile(summed[np.isfinite(summed)],5) - summed[summed>lim] = 0 - inds = np.where(ind)[0] - ref_ind = start + inds[np.argmax(summed)] - reference = deepcopy(data[ref_ind]) - if len(reference.shape) > 2: - reference = reference[0] - ref_ind = ref_ind[0] - reference[reference <= 0] = np.nan - base = np.nanmin(reference) - # reference -= base - self.ref = reference - self.ref_ind = ref_ind - # self.flux -= base - - def stack_ref(self,time_restriction=None): - if time_restriction is None: - time_restriction = self._ref_time_window - # m,med,std = sigma_clipped_stats(self.flux,axis=(1,2)) - _p = self.flux.reshape(len(self.flux), -1) - med = np.median(_p, axis=1) - std = np.median(np.abs(_p - med[:, np.newaxis]), axis=1) * 1.4826 - # sm, smed, sstd = sigma_clipped_stats(std) - smed = np.median(std) - sstd = np.median(np.abs(std - smed)) * 1.4826 - ind = np.where((std < (smed + 3*sstd)) & (std > (smed - 3*sstd)))[0] - times = self.mjd[ind] - ref_time = self.mjd[self.ref_ind] - good = abs(times - ref_time) <= time_restriction - ind = ind[good] - stack = np.nanmedian(self.flux[ind],axis=0) - self.ref = stack - + if (start is None) & (stop is None): + start = 0 + stop = len(self.flux) + elif (start is not None) & (stop is None): + stop = len(self.flux) + + elif (start is None) & (stop is not None): + start = 0 + + start = int(start) + stop = int(stop) + + ind = self.tpf.quality[start:stop] == 0 + d = deepcopy(data[start:stop])[ind] + summed = np.nansum(d,axis=(1,2)) + lim = np.percentile(summed[np.isfinite(summed)],5) + summed[summed>lim] = 0 + inds = np.where(ind)[0] + ref_ind = start + inds[np.argmax(summed)] + reference = data[ref_ind] + if len(reference.shape) > 2: + reference = reference[0] + ref_ind = ref_ind[0] + + self.ref = reference + self.ref_ind = ref_ind def centroids_shifts_starfind(self,plot=None,savename=None): """ @@ -1355,9 +780,6 @@ def centroids_shifts_starfind(self,plot=None,savename=None): """ - from PRF import TESS_PRF - from photutils.detection import StarFinder - if plot is None: plot = self.diagnostic_plot if savename is None: @@ -1370,7 +792,7 @@ def centroids_shifts_starfind(self,plot=None,savename=None): mean, med, std = sigma_clipped_stats(m, sigma=3.0) prf = TESS_PRF(self.tpf.camera,self.tpf.ccd,self.tpf.sector, - self.tpf.column+self.flux.shape[2]/2,self.tpf.row+self.flux.shape[1]/2) + self.tpf.column+self.flux.shape[2]/2,self.tpf.row+self.flux.shape[1]/2) self.prf = prf.locate(5,5,(11,11)) finder = StarFinder(2*std,kernel=self.prf,exclude_border=True) @@ -1417,7 +839,7 @@ def centroids_shifts_starfind(self,plot=None,savename=None): if savename is not None: plt.savefig(savename+'_disp.pdf', bbox_inches = "tight") - def fit_shift(self,smooth=True,plot=None,savename=None): + def fit_shift(self,plot=None,savename=None): """ Calculate the centroid shifts of sources for time series images by finding the shifts which minimize the difference between frames and reference. @@ -1432,42 +854,30 @@ def fit_shift(self,smooth=True,plot=None,savename=None): Assigns ------- shift : np.array - x,y shift of sources over the time series. + Median x,y shift of sources over the time series. """ - import matplotlib.pyplot as plt if plot is None: plot = self.diagnostic_plot if savename is None: savename = self.savename - # sources = ((self.mask & 1) ==1) * 1.0 - (convolve((self.mask & 2),np.ones((3,3))) > 0) * 1.0 - sources = ((self.mask & 1) ==1) * 1.0 - (self.mask & 2) * 1.0 + sources = ((self.mask & 1) ==1) * 1.0 - (self.mask & 2) sources[sources<=0] = 0 - sources[self.mask.shape[0]-3:self.mask.shape[0]+4,self.mask.shape[1]-3:self.mask.shape[1]+4] = 0 - f = deepcopy(self.flux) + f = self.flux m = self.ref.copy() * sources m[m==0] = np.nan - # f[f > 1e4] = np.nan - #eref = self.eflux[self.ref_ind] - if self.parallel: - ind = np.arange(len(f)) shifts = Parallel(n_jobs=self.num_cores)( - #delayed(difference_shifts)(f[i],m,self.eflux[i],eref) for i in ind) - delayed(difference_shifts)(f[i],m) for i in ind) + delayed(difference_shifts)(frame,m) for frame in f) shifts = np.array(shifts) else: shifts = np.zeros((len(f),2)) * np.nan for i in range(len(f)): - #shifts[i,:] = difference_shifts(f[i],m,self.eflux[i],eref) shifts[i,:] = difference_shifts(f[i],m) - sraw = deepcopy(shifts) - if smooth: - shifts = Smooth_motion(shifts,self.tpf) if self.shift is not None: self.shift += shifts @@ -1479,11 +889,8 @@ def fit_shift(self,smooth=True,plot=None,savename=None): ind = np.where(np.diff(t) > .5)[0] shifts[ind,:] = np.nan plt.figure(figsize=(1.5*fig_width,1*fig_width)) - plt.plot(t,sraw[:,0],'.',label='Row shift',alpha = 0.5) - plt.plot(t,sraw[:,1],'.',label='Col shift',alpha = 0.5) - if smooth: - plt.plot(t,shifts[:,0],'-',label='Smoothed row shift') - plt.plot(t,shifts[:,1],'-',label='Smoothed col shift') + plt.plot(t,shifts[:,0],'.',label='Row shift',alpha =0.5) + plt.plot(t,shifts[:,1],'.',label='Col shift',alpha =0.5) plt.ylabel('Shift (pixels)',fontsize=15) plt.xlabel('Time (MJD)',fontsize=15) plt.legend() @@ -1491,23 +898,6 @@ def fit_shift(self,smooth=True,plot=None,savename=None): if savename is not None: plt.savefig(savename+'_disp_corr.pdf', bbox_inches = "tight") - def plot_shifts(self,savename=None): - import matplotlib.pyplot as plt - t = self.tpf.time.mjd - shifts = self.shift - ind = np.where(np.diff(t) > .5)[0] - shifts[ind,:] = np.nan - plt.figure(figsize=(1.5*fig_width,1*fig_width)) - plt.plot(t,shifts[:,0],'.',label='Row shift',alpha =0.5) - plt.plot(t,shifts[:,1],'.',label='Col shift',alpha =0.5) - plt.ylabel('Shift (pixels)',fontsize=15) - plt.xlabel('Time (MJD)',fontsize=15) - plt.legend() - plt.show() - plt.tight_layout() - if savename is not None: - plt.savefig(savename+'_alignment.pdf', bbox_inches = "tight") - def shift_images(self,median=False): """ Shifts each target image to the reference using the values given in offset. Breaks horribly if data is all 0. @@ -1530,7 +920,7 @@ def shift_images(self,median=False): if median: for i in range(len(shifted)): if np.nansum(abs(shifted[i])) > 0: - shifted[i] = shift(self.ref,[-self.shift[i,1],-self.shift[i,0]], mode='nearest',order=5) + shifted[i] = shift(self.ref,[-self.shift[i,1],-self.shift[i,0]]) self.flux -= shifted else: @@ -1648,28 +1038,8 @@ def bin_flux(self,flux=None,time_bin=6/24,frames = None): bint = np.array(points) return binf, bint - def check_trend(self,lc=None,limit=0.6): - from scipy.stats import pearsonr - if lc is None: - lc = self.lc[1] - #print('!!!! ',lc.shape) - finite = np.isfinite(lc) & np.isfinite(self.shift[:,0]) & np.isfinite(self.shift[:,1]) - p1 = pearsonr(lc[finite],self.shift[finite,0])[0] - p2 = pearsonr(lc[finite],self.shift[finite,1])[0] - if (abs(p1) > limit) | (abs(p2) > limit): - if abs(p1) > abs(p2): - m = 'x shift' - p = p1 - else: - m = 'y shift' - p = p2 - print(f'High correlation between lc and {m}: {np.round(p,2)}') - return np.max([p1,p2]) - - def diff_lc(self,time=None,x=None,y=None,ra=None,dec=None,tar_ap=3, - sky_in=5,sky_out=9,phot_method=None,psf_snap='brightest', - bkg_poly_order=3,plot=None,savename=None,mask=None,diff = True): + sky_in=5,sky_out=9,phot_method=None,psf_snap='brightest',plot=None,savename=None,mask=None,diff = True): """ Calculate the difference imaged light curve. if no position is given (x,y or ra,dec) then it degaults to the centre. Sky flux is calculated with an annulus aperture surrounding @@ -1713,8 +1083,6 @@ def diff_lc(self,time=None,x=None,y=None,ra=None,dec=None,tar_ap=3, DESCRIPTION. """ - import matplotlib.pyplot as plt - if plot is None: plot = self.diagnostic_plot if savename is None: @@ -1739,12 +1107,12 @@ def diff_lc(self,time=None,x=None,y=None,ra=None,dec=None,tar_ap=3, if (ra is not None) & (dec is not None) & (self.tpf is not None): x,y = self.wcs.all_world2pix(ra,dec,0) - x = int(np.round(x,0)) - y = int(np.round(y,0)) + x = int(x + 0.5) + y = int(y + 0.5) elif (x is None) & (y is None): x,y = self.wcs.all_world2pix(self.ra,self.dec,0) - x = int(np.round(x,0)) - y = int(np.round(y,0)) + x = int(x + 0.5) + y = int(y + 0.5) ap_tar = np.zeros_like(data[0]) ap_sky = np.zeros_like(data[0]) @@ -1774,49 +1142,19 @@ def diff_lc(self,time=None,x=None,y=None,ra=None,dec=None,tar_ap=3, else: tar = np.nansum((data+self.ref)*ap_tar,axis=(1,2)) tar -= sky_med * tar_ap**2 - if self._use_error_image: - tar_err = np.nansum((self.eflux)*ap_tar,axis=(1,2))#sky_std * tar_ap**2 - else: - tar_err = sky_std * tar_ap**2 + tar_err = sky_std * tar_ap**2 if phot_method == 'psf': if psf_snap is None: psf_snap = 'brightest' - tar, tar_err = self.psf_photometry(x,y,diff=diff,snap=psf_snap,bkg_poly_order=bkg_poly_order) - elif phot_method == 'photutils': - if psf_snap is None: - psf_snap = 'brightest' - tar, tar_err = self.psf_photutils(xPix=x, yPix=y, snap=psf_snap) + tar, tar_err = self.psf_photometry(x,y,diff=diff,snap=psf_snap) nan_ind = np.where(np.nansum(self.flux,axis=(1,2))==0,True,False) nan_ind[self.ref_ind] = False tar[nan_ind] = np.nan tar_err[nan_ind] = np.nan - # ── Orbit ref flux correction ────────────────────────────────────────── - if self.orbit_ref and hasattr(self, 'orbit_refs') and hasattr(self, 'orbit_segments'): - orb_flux = {} - orb_err = {} - for seg, ref_im in self.orbit_refs.items(): - f = np.nansum(ref_im * ap_tar) - np.nanmedian(ref_im * ap_sky) * tar_ap**2 - sky_vals = ref_im * ap_sky - e = np.nanstd(sky_vals[np.isfinite(sky_vals)]) * tar_ap**2 - orb_flux[seg] = f - orb_err[seg] = e - - # primary = orbit whose ref has lowest stddev - primary_seg = min(self.orbit_refs, key=lambda s: np.nanstd(self.orbit_refs[s])) - f_primary = orb_flux[primary_seg] - e_primary = orb_err[primary_seg] - - for seg in self.orbit_refs: - if seg == primary_seg: - continue - delta = orb_flux[seg] - f_primary - delta_err = np.sqrt(orb_err[seg]**2 + e_primary**2) - if np.abs(delta) > delta_err: - mask = self.orbit_segments == seg - tar[mask] += delta - + #tar[tar_err > 100] = np.nan + #sky_med[tar_err > 100] = np.nan if self.tpf is not None: time = self.tpf.time.mjd lc = np.array([time, tar, tar_err]) @@ -1827,8 +1165,6 @@ def diff_lc(self,time=None,x=None,y=None,ra=None,dec=None,tar_ap=3, plt.show() if savename is not None: plt.savefig(savename + '_diff_diag.pdf', bbox_inches = "tight") - - #p = self.check_trend(lc=lc[1]) return lc, sky def dif_diag_plot(self,ap_tar,ap_sky,lc=None,sky=None,data=None): @@ -1854,7 +1190,6 @@ def dif_diag_plot(self,ap_tar,ap_sky,lc=None,sky=None,data=None): Figure. """ - import matplotlib.pyplot as plt if lc is None: lc = self.lc @@ -1886,9 +1221,9 @@ def dif_diag_plot(self,ap_tar,ap_sky,lc=None,sky=None,data=None): nonan1 = np.isfinite(d) nonan2 = np.isfinite(d*ap) plt.imshow(data[maxind],origin='lower', - vmin=np.nanpercentile(d,8), - vmax=np.nanpercentile(d[nonan2],80), - aspect='auto') + vmin=np.nanpercentile(d,16), + vmax=np.nanpercentile(d[nonan2],80), + aspect='auto') cbar = plt.colorbar() cbar.set_label('$e^-/s$',fontsize=15) plt.xlabel('Column',fontsize=15) @@ -1926,7 +1261,6 @@ def plotter(self,lc=None,ax = None,ground=False,time_bin=6/24,xlims=None): Figure. """ - import matplotlib.pyplot as plt if ground: if self.ground.ztf is None: @@ -2050,9 +1384,6 @@ def to_lightkurve(self,lc=None,flux_unit=None): The input lightcurve wrapped in the lightkurve format. """ - from astropy import units as u - from astropy.time import Time - if lc is None: lc = self.lc if flux_unit is None: @@ -2170,38 +1501,20 @@ def _psf_initialise(self,cutoutSize,loc,time_ind=None,ref=False): if time_ind is None: time_ind = np.arange(0,len(self.flux)) - - col = self.tpf.column - int(self.size//2) + loc[0] # find column and row, when specifying location on a *say* 90x90 px cutout - row = self.tpf.row - int(self.size//2) + loc[1] - if isinstance(loc[0], (float, np.floating, np.float32, np.float64)): - loc[0] = int(np.round(loc[0],0)) + loc[0] = int(loc[0] + 0.5) if isinstance(loc[1], (float, np.floating, np.float32, np.float64)): - loc[1] = int(np.round(loc[1])) - - col += 45 # add on the non-science columns - row += 1 # add on the non-science row - if col > 2090: - col = 2090 - if row > 2040: - row = 2040 - row = np.max([row,10]) - col = np.max([col,45]) - try: - prf = TESS_PRF(self.tpf.camera,self.tpf.ccd,self.tpf.sector,col,row) # initialise psf kernel - except: - print(self.tpf.camera,self.tpf.ccd,self.tpf.sector,col,row) - raise ValueError + loc[1] = int(loc[1] + 0.5) + + col = self.tpf.column - int(self.size/2-1) + loc[0] # find column and row, when specifying location on a *say* 90x90 px cutout + row = self.tpf.row - int(self.size/2-1) + loc[1] + + prf = TESS_PRF(self.tpf.camera,self.tpf.ccd,self.tpf.sector,col,row) # initialise psf kernel if ref: cutout = (self.flux+self.ref)[time_ind,loc[1]-cutoutSize//2:loc[1]+1+cutoutSize//2,loc[0]-cutoutSize//2:loc[0]+1+cutoutSize//2] # gather cutouts else: cutout = self.flux[time_ind,loc[1]-cutoutSize//2:loc[1]+1+cutoutSize//2,loc[0]-cutoutSize//2:loc[0]+1+cutoutSize//2] # gather cutouts - if self._use_error_image: - ecutout = self.eflux[time_ind,loc[1]-cutoutSize//2:loc[1]+1+cutoutSize//2,loc[0]-cutoutSize//2:loc[0]+1+cutoutSize//2] # gather cutouts - else: - ecutout = np.ones_like(cutout) * 0.1 - #else: - return prf, cutout, ecutout + return prf, cutout def moving_psf_photometry(self,xpos,ypos,size=5,time_ind=None,xlim=2,ylim=2): """ @@ -2238,14 +1551,14 @@ def moving_psf_photometry(self,xpos,ypos,size=5,time_ind=None,xlim=2,ylim=2): raise ValueError(m) inds = np.arange(0,len(xpos)) if self.parallel: - prfs, cutouts, ecutouts = zip(*Parallel(n_jobs=self.num_cores)(delayed(par_psf_initialise)(self.flux,self.tpf.camera,self.tpf.ccd, - self.tpf.sector,self.tpf.column,self.tpf.row, - size,[xpos[i],ypos[i]],time_ind) for i in inds)) + prfs, cutouts = zip(*Parallel(n_jobs=self.num_cores)(delayed(par_psf_initialise)(self.flux,self.tpf.camera,self.tpf.ccd, + self.tpf.sector,self.tpf.column,self.tpf.row, + size,[xpos[i],ypos[i]],time_ind) for i in inds)) else: prfs = [] cutouts = [] for i in range(len(time_ind)): - prf, cutout, ecutouts = self._psf_initialise(size,[xpos[i],ypos[i]],time_ind=time_ind[i]) + prf, cutout = self._psf_initialise(size,[xpos[i],ypos[i]],time_ind=time_ind[i]) prfs += [prf] cutouts += [cutout] cutouts = np.array(cutouts) @@ -2264,100 +1577,7 @@ def moving_psf_photometry(self,xpos,ypos,size=5,time_ind=None,xlim=2,ylim=2): pos[0,:] += xpos; pos[1,:] += ypos return flux, pos - def psf_photutils(self,xPix=None,yPix=None,size=5,local_bkg=False,epsf=None, - flux=None,eflux=None,ref=False,return_pos=False, - snap='brightest'): - from photutils.psf import PSFPhotometry - from astropy.table import Table - rad = size // 2 - - if flux is None: - flux = self.flux - if (flux.shape[1] < size) | (flux.shape[2] < size): - e = 'Image dimensions must be larger than the cutout size' - raise ValueError(e) - if eflux is None: - eflux = self.eflux - if eflux is None: - f = strip_units(flux) - eflux = np.nanstd(f, axis=(1, 2))[:, np.newaxis, np.newaxis] * np.ones_like(f) - - if (xPix is None) | (yPix is None): - xPix = flux.shape[2]//2 - yPix = flux.shape[1]//2 - - if epsf is None: - if self.epsf is None: - col = self.tpf.column - int(self.size//2) + yPix # find column and row, when specifying location on a *say* 90x90 px cutout - row = self.tpf.row - int(self.size//2) + xPix - col += 45 # add on the non-science columns - row += 1 # add on the non-science row - if col > 2090: - col = 2090 - if row > 2040: - row = 2040 - - self.epsf = simulate_epsf(self.tpf.camera,self.tpf.ccd,self.tpf.sector,col,row) - epsf = self.epsf - - if local_bkg: - localbkg_estimator = LocalBackground(1.5, 7, bkgstat) - else: - localbkg_estimator = None - - if ref: - flux = flux + self.ref - - cutouts = flux[:,yPix-rad:yPix+rad+1,xPix-rad:xPix+rad+1] - ecutouts = eflux[:,yPix-rad:yPix+rad+1,xPix-rad:xPix+rad+1] - fit_shape = (size, size) - psfphot = PSFPhotometry(epsf, fit_shape, finder=None,aperture_radius=1.5, - localbkg_estimator=localbkg_estimator,xy_bounds=(0.05)) - init = Table() - init['x_init'] = [size//2] - init['y_init'] = [size//2] - if snap.lower() != 'all': - if snap.lower() == 'brightest': - weight = np.abs(np.nansum((cutouts/ecutouts)[:,1:4,1:4],axis=(1,2))) - weight[np.isnan(weight)] = 0 - ind = np.argmax(weight) - rcut = cutouts[ind] - ecut = ecutouts[ind] - elif snap.lower() == 'ref': - rcut = self.ref[:,yPix-rad:yPix+rad+1,xPix-rad:xPix+rad+1] - ecut = ecutouts[self.ref_ind] - - - phot = psfphot(rcut, error=ecut,init_params=init) - # fit with the best position - init2 = Table() - init['x_init'] = phot['x_fit'] - init['y_init'] = phot['y_fit'] - flux = np.zeros(len(self.flux)) * np.nan - eflux = np.zeros(len(self.flux)) * np.nan - psfphot2 = PSFPhotometry(epsf, fit_shape, finder=None,aperture_radius=1.5, - xy_bounds=(0.05),localbkg_estimator=localbkg_estimator) - f,ef = zip(*Parallel(n_jobs=self.num_cores)(delayed(parallel_photutils)(cutouts[i],ecutouts[i],psfphot2,init) for i in np.arange(len(cutouts)))) - f = np.array(f).flatten() - ef = np.array(ef).flatten() - phot = phot.to_pandas() - pos = phot[['x_fit','y_fit']].values + np.array([xPix,yPix]) - size//2 - epos = phot[['x_err','y_err']].values - else: - f,ef,pos,epos = zip(*Parallel(n_jobs=self.num_cores)(delayed(parallel_photutils)(cutouts[i],ecutouts[i],psfphot,init,True) for i in np.arange(len(cutouts)))) - pos['x_fit'] += xPix - size//2 - pos['y_fit'] += xPix - size//2 - - if return_pos: - return f, ef, pos, epos - else: - return f, ef - - - - - - def psf_photometry(self,xPix,yPix,size=7,snap='brightest',ext_shift=True,plot=False,diff=None,bkg_poly_order=3): + def psf_photometry(self,xPix,yPix,size=7,snap='brightest',ext_shift=True,plot=False,diff=None): """ Main PSF Photometry function @@ -2394,23 +1614,22 @@ def psf_photometry(self,xPix,yPix,size=7,snap='brightest',ext_shift=True,plot=Fa """ - from .psf_photom import create_psf - if diff is None: diff = self.diff flux = [] + eflux = [] # if isinstance(xPix,(list,np.ndarray)): - # self.moving_psf_phot() + # self.moving_psf_phot() if type(snap) == str: if snap == 'all': - prf, cutouts, ecutouts = self._psf_initialise(size,(xPix,yPix),ref=(not diff)) # gather base PRF and the array of cutouts data + prf, cutouts = self._psf_initialise(size,(xPix,yPix),ref=(not diff)) # gather base PRF and the array of cutouts data inds = np.arange(len(cutouts)) base = create_psf(prf,size) flux, eflux, pos = zip(*Parallel(n_jobs=self.num_cores)(delayed(par_psf_full)(cutouts[i],base,self.shift[i]) for i in inds)) - #prf, cutouts = self._psf_initialise(size,(xPix,yPix)) # gather base PRF and the array of cutouts data + #prf, cutouts = self._psf_initialise(size,(xPix,yPix)) # gather base PRF and the array of cutouts data #xShifts = [] #yShifts = [] #for cutout in tqdm(cutouts): @@ -2430,108 +1649,56 @@ def psf_photometry(self,xPix,yPix,size=7,snap='brightest',ext_shift=True,plot=Fa # ax[2].set_ylabel('yShift') else: if snap == 'brightest': # each cutout has position snapped to brightest frame fit position - prf, cutouts, ecutouts = self._psf_initialise(size,(xPix,yPix),ref=(not diff)) # gather base PRF and the array of cutouts data + prf, cutouts = self._psf_initialise(size,(xPix,yPix),ref=(not diff)) # gather base PRF and the array of cutouts data bkg = self.bkg[:,int(yPix),int(xPix)] - #lowbkg = bkg < np.nanpercentile(bkg,8) - #weight = np.abs(np.nansum(cutouts[:,int(yPix)-1:int(yPix)+2,int(xPix)-1:int(xPix)+2],axis=(1,2))) / bkg - weight = np.abs(np.nansum((cutouts / ecutouts)[:,int(yPix)-1:int(yPix)+2,int(xPix)-1:int(xPix)+2],axis=(1,2))) + #lowbkg = bkg < np.nanpercentile(bkg,16) + weight = np.nansum(cutouts[:,int(yPix)-1:int(yPix)+2,int(xPix)-1:int(xPix)+2],axis=(1,2)) / bkg weight[np.isnan(weight)] = 0 - ind = np.argmax(weight) + ind = np.argmax(abs(weight)) #ind = np.where(cutouts==np.nanmax(cutouts))[0][0] ref = cutouts[ind] base = create_psf(prf,size) - base.psf_position(ref,ecutouts[ind],ext_shift=self.shift[ind]) + base.psf_position(ref,ext_shift=self.shift[ind]) elif snap == 'ref': - prf, cutouts,ecutouts = self._psf_initialise(size,(xPix,yPix),ref=True) # gather base PRF and the array of cutouts data + prf, cutouts = self._psf_initialise(size,(xPix,yPix),ref=True) # gather base PRF and the array of cutouts data ref = cutouts[self.ref_ind] base = create_psf(prf,size) - base.psf_position(ref,ecutouts[self.ref_ind]) + base.psf_position(ref) if diff: - _, cutouts,ecutouts = self._psf_initialise(size,(xPix,yPix),ref=False) - elif snap == 'fixed': - prf, cutouts, ecutouts = self._psf_initialise(size,(xPix,yPix),ref=(not diff)) # gather base PRF and the array of cutouts data - base = create_psf(prf,size) + _, cutouts = self._psf_initialise(size,(xPix,yPix),ref=False) if self.parallel: inds = np.arange(len(cutouts)) - if self.delta_kernel is not None: - flux, eflux = zip(*Parallel(n_jobs=self.num_cores)(delayed(par_psf_flux)(cutouts[i],ecutouts[i],base,self.shift[i],bkg_poly_order,self.delta_kernel[i]) for i in inds)) - else: - flux, eflux = zip(*Parallel(n_jobs=self.num_cores)(delayed(par_psf_flux)(cutouts[i],ecutouts[i],base,self.shift[i],bkg_poly_order) for i in inds)) + flux, eflux = zip(*Parallel(n_jobs=self.num_cores)(delayed(par_psf_flux)(cutouts[i],base,self.shift[i]) for i in inds)) else: + print('Non-parallell') for i in range(len(cutouts)): - flux += [par_psf_flux(cutouts[i],ecutouts[i],base,self.shift[i])] + flux += [par_psf_flux(cutouts[i],base,self.shift[i])[0]] + eflux += [par_psf_flux(cutouts[i],base,self.shift[i])[1]] if plot: plt.figure() plt.plot(flux) plt.ylabel('Flux') - elif type(snap) == int: # each cutout has position snapped to 'snap' frame fit position (snap is integer) + elif type(snap) == int: # each cutout has position snapped to 'snap' frame fit position (snap is integer) base = create_psf(prf,size) base.psf_position(cutouts[snap]) - if self.parallel: - inds = np.arange(len(cutouts)) - if self.delta_kernel is not None: - flux, eflux = zip(*Parallel(n_jobs=self.num_cores)(delayed(par_psf_flux)(cutouts[i],ecutouts[i],base,self.shift[i],bkg_poly_order,self.delta_kernel[i]) for i in inds)) - else: - flux, eflux = zip(*Parallel(n_jobs=self.num_cores)(delayed(par_psf_flux)(cutouts[i],ecutouts[i],base,self.shift[i],bkg_poly_order) for i in inds)) - else: - for i in range(len(cutouts)): - flux += [par_psf_flux(cutouts[i],ecutouts[i],base,self.shift[i])] + for cutout in cutouts: + PSF = create_psf(prf,size) + PSF.source_x = base.source_x + PSF.source_y = base.source_y + PSF.psf_flux(cutout) + flux.append(PSF.flux) if plot: fig,ax = plt.subplots(ncols=1,figsize=(12,4)) ax.plot(flux) ax.set_ylabel('Flux') flux = np.array(flux) + # print('New flux shape:', flux.shape) eflux = np.array(eflux) return flux, eflux - def orbit_ref_subtract(self): - """ - Subtract a per-orbit reference from each orbit's frames. - - Orbit assignments are obtained from TESSVectors if available, otherwise - derived from time gaps > 0.5 days. For each orbit the reference is the - median stack of that orbit's frames. A smoothed additive correction maps - the primary orbit reference onto each secondary orbit before subtraction. - - Updates self.flux in place and stores self.orbit_segments. - """ - sector = (self.tpf.sector if self.tpf is not None else None) or self.sector - camera = (self.tpf.camera if self.tpf is not None else None) or self.camera - flux, segments, orbit_refs = orbit_ref_subtract(deepcopy(self.flux), self.mjd, - sector=sector, camera=camera, - vector_path=self._vector_path) - self.flux = flux - self.orbit_segments = segments - self.orbit_refs = orbit_refs - if self.verbose > 0: - orbs, counts = np.unique(segments, return_counts=True) - print(f'Orbit ref subtraction: {dict(zip(orbs, counts))} frames per orbit') - - def kernel_matching(self,size=7,diff=True): - from .delta_function_fitting import parallel_delta_diff - if diff: - flux = deepcopy(self.flux + self.ref) - else: - flux = deepcopy(self.flux) - mask = self.mask == 1 - - if self.parallel: - d, kernel = zip(*Parallel(n_jobs=self.num_cores)(delayed(parallel_delta_diff)(frame,self.ref,mask,size) for frame in flux)) - else: - d = [] - kernel = [] - for frame in flux: - tmp = parallel_delta_diff(frame,self.ref,mask,size) - d += [tmp[0]] - kernel += [tmp[1]] - d = np.array(d) - self.delta_kernel = np.array(kernel) - self.flux = d - - def reduce(self, aper = None, align = None, parallel = None, calibrate=None, bin_size = 0, plot = None, mask_scale = 1, ref_start=None, ref_stop=None, diff_lc = None,diff=None,verbose=None, tar_ap=3,sky_in=7,sky_out=11, @@ -2595,8 +1762,6 @@ def reduce(self, aper = None, align = None, parallel = None, calibrate=None, """ # make reference try: - _times = {} - _t0_total = time.perf_counter() self._update_reduction_params(align, parallel, calibrate, plot, diff_lc, diff, verbose,corr_correction,imaging) if (self.flux.shape[1] < 30) & (self.flux.shape[2] < 30): @@ -2608,53 +1773,40 @@ def reduce(self, aper = None, align = None, parallel = None, calibrate=None, print('Unlikely to get good shifts from a small tpf, so shift has been set to False') self.align = False - _t = time.perf_counter() self.get_ref(ref_start,ref_stop) - _times['reference frame'] = time.perf_counter() - _t if self.verbose > 0: print('made reference') # make source mask - _t = time.perf_counter() if mask is None: self.make_mask(catalogue_path=self._catalogue_path,maglim=18,strapsize=7,scale=mask_scale) frac = np.nansum((self.mask == 0) * 1.) / (self.mask.shape[0] * self.mask.shape[1]) #print('mask frac ',frac) if frac < 0.05: print('!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.') - self.make_mask(catalogue_path=self._catalogue_path,maglim=15,strapsize=7,scale=0.2) + self.make_mask(catalogue_path=self._catalogue_path,maglim=15,strapsize=7,scale=0.5) if self.verbose > 0: print('made source mask') else: self.mask = mask if self.verbose > 0: print('assigned source mask') - if moving_mask is not None: - moving_mask = moving_mask > 0 - temp = np.zeros_like(self.flux,dtype=int) - temp[:,:,:] = self.mask - self.mask = temp | moving_mask - _times['source mask'] = time.perf_counter() - _t # calculate background for each frame if self.verbose > 0: print('calculating background') # calculate the background - #self.flux -= self.ref - _t = time.perf_counter() - self.background(rerun_negative=True) - #self.flux += self.ref - self.flux -= self.bkg - _times['background (pass 1)'] = time.perf_counter() - _t + self.background() + if np.isnan(self.bkg).all(): # check to see if the background worked raise ValueError('bkg all nans') - # flux = strip_units(self.flux) + flux = strip_units(self.flux) # subtract background from unitless flux - # self.flux = flux - self.bkg + self.flux = flux - self.bkg # get a ref with low background - # self.ref = deepcopy(self.flux[self.ref_ind]) + self.ref = deepcopy(self.flux[self.ref_ind]) if self.verbose > 0: print('background subtracted') @@ -2662,61 +1814,40 @@ def reduce(self, aper = None, align = None, parallel = None, calibrate=None, if np.isnan(self.flux).all(): raise ValueError('flux all nans') - _t = time.perf_counter() if self.align: if self.verbose > 0: print('aligning images') - - # try: - if self._shift_method == 'centroid': - self.centroids_shifts_starfind() - elif self._shift_method == 'difference': - self.fit_shift(smooth=self._smooth_motion) - elif self._shift_method == 'sep_core': - from .sep_aligner import SepAligner - aligner = SepAligner.from_tessreduce(self) - aligner.run() - if self._smooth_motion: - aligner.smooth_shift(time=self.mjd, - gap_thresh=0.5, # days - update_shift=True) - self.shift = aligner.shift - else: - m = f'Shift method {self._shift_method} is not supported, choose from:\ncentroid\ndifference\nsep_core' - raise ValueError(m) + + try: + #self.centroids_shifts_starfind() #if double_shift: #self.shift_images() #self.ref = deepcopy(self.flux[self.ref_ind]) - + self.fit_shift() #self.shift_images() - - # except: - # print('Something went wrong, switching to serial') - # self.parallel = False - # if self._shift_method == 'centroid': - # self.centroids_shifts_starfind() - # elif self._shift_method == 'minimize': - # self.fit_shift() + + except: + print('Something went wrong, switching to serial') + self.parallel = False + #self.centroids_shifts_starfind() + self.fit_shift() + #self.fit_shift() + #self.fit_shift() else: self.shift = np.zeros((len(self.flux),2)) - _times['alignment'] = time.perf_counter() - _t if not self.diff: if self.align: - _t = time.perf_counter() self.shift_images() self.flux[np.nansum(self.tpf.flux.value,axis=(1,2))==0] = np.nan - _times['image shifting'] = time.perf_counter() - _t if self.verbose > 0: print('images shifted') - #if self.kernel_match: - # self.kernel_matching(diff=False) if self.diff: if self.verbose > 0: print('!!Re-running for difference image!!') - # reseting to do diffim - _t = time.perf_counter() + # reseting to do diffim + self._flux_aligned = deepcopy(self.flux) self.flux = strip_units(self.tpf.flux) self.flux = self.flux / self.qe @@ -2725,41 +1856,32 @@ def reduce(self, aper = None, align = None, parallel = None, calibrate=None, if self.verbose > 0: print('shifting images') - self._flux_aligned = deepcopy(self.flux) + if test_seed is not None: self.flux += test_seed self.flux[np.nansum(self.tpf.flux.value,axis=(1,2))==0] = np.nan # subtract reference - if self._ref_type.lower() == 'single': - self.ref = deepcopy(self.flux[self.ref_ind]) - elif self._ref_type.lower() == 'stack': - self.stack_ref() - self.ref -= np.nanmin(self.ref) + self.ref = deepcopy(self.flux[self.ref_ind]) self.flux -= self.ref - # self.ref -= self.bkg[self.ref_ind] - self._ref_bkg = self.bkg[self.ref_ind] + self.ref -= self.bkg[self.ref_ind] # remake mask - self.make_mask(catalogue_path=self._catalogue_path,maglim=13,strapsize=7,scale=mask_scale*.5,useref=False)#Source_mask(ref,grid=0) + self.make_mask(catalogue_path=self._catalogue_path,maglim=18,strapsize=7,scale=mask_scale*.8,useref=False)#Source_mask(ref,grid=0) frac = np.nansum((self.mask== 0) * 1.) / (self.mask.shape[0] * self.mask.shape[1]) #print('mask frac ',frac) if frac < 0.05: print('!!!WARNING!!! mask is too dense, lowering mask_scale to 0.5, and raising maglim to 15. Background quality will be reduced.') - self.make_mask(catalogue_path=self._catalogue_path,maglim=11,strapsize=7,scale=mask_scale*.5*.5) - # assuming that the target is in the centre, so masking it out + self.make_mask(catalogue_path=self._catalogue_path,maglim=15,strapsize=7,scale=0.5) + # assuming that the target is in the centre, so masking it out #m_tar = np.zeros_like(self.mask,dtype=int) #m_tar[self.ref.shape[0]//2,self.ref.shape[1]//2]= 1 #m_tar = convolve(m_tar,np.ones((5,5))) #self.mask = self.mask | m_tar - #mask - #mask = convolve(self.mask,np.ones((3,3))) > 1 - #elf.mask = mask if moving_mask is not None: moving_mask = moving_mask > 0 temp = np.zeros_like(self.flux,dtype=int) temp[:,:,:] = self.mask self.mask = temp | moving_mask - _times['difference imaging setup'] = time.perf_counter() - _t if self.verbose > 0: print('remade mask') @@ -2767,53 +1889,27 @@ def reduce(self, aper = None, align = None, parallel = None, calibrate=None, if self.verbose > 0: print('background') self.bkg_orig = deepcopy(self.bkg) - _t = time.perf_counter() - self.background(calc_qe = False,strap_iso = False,source_hunt=self._sourcehunt, - gauss_smooth=self._bkg_gauss_sigma,interpolate=False, - rerun_negative=False,rerun_diff=True,blend_dynamic=True) - # self._grad_bkg_clip() + self.background(calc_qe = False,strap_iso = False,source_hunt=self._sourcehunt,gauss_smooth=1,interpolate=False) + self._grad_bkg_clip() self.flux -= self.bkg - _times['background (pass 2)'] = time.perf_counter() - _t - if self.corr_correction: - _t = time.perf_counter() if self.verbose > 0: print('background correlation correction') self.correlation_corrector() - _times['correlation correction'] = time.perf_counter() - _t - if self.kernel_match: - self.kernel_matching(diff=self.diff) - if self.verbose > 0: - print('kernels matched') - if self.orbit_ref: - if self.verbose > 0: - print('orbit ref subtraction') - self.orbit_ref_subtract() if self.calibrate: - _t = time.perf_counter() print('field calibration') self.field_calibrate() - _times['field calibration'] = time.perf_counter() - _t - if self._create_lc: - _t = time.perf_counter() - self.lc, self.sky = self.diff_lc(plot=self.plot,diff=self.diff,tar_ap=tar_ap,sky_in=sky_in,sky_out=sky_out) - _times['light curve'] = time.perf_counter() - _t + + self.lc, self.sky = self.diff_lc(plot=self.plot,diff=self.diff,tar_ap=tar_ap,sky_in=sky_in,sky_out=sky_out) if self.imaging: # if self.verbose > 0: # print('Retrieving external photometry') self.external_photometry() - if self._timing: - _total = time.perf_counter() - _t0_total - print('\nReduce timing report:') - for _name, _elapsed in _times.items(): - print(f' {_name:<35s} {_elapsed:6.2f}s ({100*_elapsed/_total:5.1f}%)') - print(f' {"total":<35s} {_total:6.2f}s') - except Exception: print(traceback.format_exc()) @@ -2873,7 +1969,7 @@ def make_lc(self,aperture = None,bin_size=0,zeropoint=None,scale='counts',clip = elif type(aperture) == np.ndarray: aper = aperture * 1. - lc = Lightcurve(flux,aper) #,scale = scale) + lc = Lightcurve(flux,aper) #,scale = scale) if clip: mask = ~sigma_mask(lc) lc[mask] = np.nan @@ -2944,8 +2040,6 @@ def event_plotter(self,**kwargs): None. """ - import matplotlib.pyplot as plt - if self.events is None: self.lc_events(**kwargs) plt.figure() @@ -2994,9 +2088,7 @@ def detrend_transient(self,lc=None,err=None,Mask=None,variable=False,sig = 5, Lightcurve with the stellar trends subtracted. """ - import matplotlib.pyplot as plt - - # Make a smoothing value with a significant portion of the total + # Make a smoothing value with a significant portion of the total if lc is None: lc = self.lc[:2] @@ -3245,7 +2337,7 @@ def bin_interp(self,lc=None,time_bin=6/24): smooth = f1(lc[0]) return smooth - def detrend_star(self,lc=None,normalize=False): + def detrend_star(self,lc=None): """ Removes trends, e.g. background or stellar variability from the lightcurve data. @@ -3292,10 +2384,7 @@ def detrend_star(self,lc=None,normalize=False): smooth = f1(temp[0]) detrended = deepcopy(lc) - if normalize: - detrended[1] /= smooth - else: - detrended[1] -= smooth + detrended[1] -= smooth return detrended @@ -3360,12 +2449,12 @@ def isolated_star_lcs(self): ind = dist < 1.5 close = tab.iloc[ind] - d.loc[i,'gmag'] = -2.5*np.log10(np.nansum(maselfflux(close.gmag.values,25))) + 25 - d.loc[i,'rmag'] = -2.5*np.log10(np.nansum(maselfflux(close.rmag.values,25))) + 25 - d.loc[i,'imag'] = -2.5*np.log10(np.nansum(maselfflux(close.imag.values,25))) + 25 - d.loc[i,'zmag'] = -2.5*np.log10(np.nansum(maselfflux(close.zmag.values,25))) + 25 + d['gmag'].iloc[i] = -2.5*np.log10(np.nansum(mag2flux(close.gmag.values,25))) + 25 + d['rmag'].iloc[i] = -2.5*np.log10(np.nansum(mag2flux(close.rmag.values,25))) + 25 + d['imag'].iloc[i] = -2.5*np.log10(np.nansum(mag2flux(close.imag.values,25))) + 25 + d['zmag'].iloc[i] = -2.5*np.log10(np.nansum(mag2flux(close.zmag.values,25))) + 25 if system == 'ps1': - d.loc[i,'ymag'] = -2.5*np.log10(np.nansum(maselfflux(close.ymag.values,25))) + 25 + d['ymag'].iloc[i] = -2.5*np.log10(np.nansum(mag2flux(close.ymag.values,25))) + 25 # convert to tess mags if len(d) < 10: print('!!!WARNING!!! field calibration is unreliable, using the default zp = 20.44') @@ -3387,11 +2476,11 @@ def isolated_star_lcs(self): for i in range(len(d)): #if self.phot_method == 'aperture': mask = np.zeros_like(self.ref) - mask[int(np.round(d.row.values[i],0)),int(np.round(d.col.values[i],0))] = 1 + mask[int(d.row.values[i] + .5),int(d.col.values[i] + .5)] = 1 mask = convolve(mask,np.ones((3,3))) flux += [np.nansum(tflux*mask,axis=(1,2))] m2 = np.zeros_like(self.ref) - m2[int(np.round(d.row.values[i],0)),int(np.round(d.col.values[i]))] = 1 + m2[int(d.row.values[i] + .5),int(d.col.values[i] + .5)] = 1 m2 = convolve(m2,np.ones((7,7))) - convolve(m2,np.ones((5,5))) eflux += [np.nansum(tflux*m2,axis=(1,2))] mag = -2.5*np.log10(np.nansum((self.ref*m2))) + 20.44 @@ -3446,7 +2535,6 @@ def field_calibrate(self,zp_single=True,plot=None,savename=None): Error in the photometric zeropoint """ - import matplotlib.pyplot as plt if plot is None: plot = self.diagnostic_plot @@ -3456,10 +2544,8 @@ def field_calibrate(self,zp_single=True,plot=None,savename=None): if self.verbose > 0: print('target is below -30 dec, calibrating to SkyMapper photometry.') table = Get_Catalogue(self.tpf,Catalog='skymapper') + #table = Skymapper_df(table) system = 'skymapper' - if table is None: - print('WARNING: SkyMapper unavailable, skipping field calibration.') - return else: if self.verbose > 0: print('target is above -30 dec, calibrating to PS1 photometry.') @@ -3482,32 +2568,31 @@ def field_calibrate(self,zp_single=True,plot=None,savename=None): tflux = self.flux - ind = (table.imag.values < 19) & (table.imag.values > 13.5) + ind = (table.imag.values < 19) & (table.imag.values > 14) tab = table.iloc[ind] e, dat = Tonry_reduce(tab,plot=plot,savename=savename,system=system) self.ebv = e[0] - gr = (dat.gmag - dat['rmag']).values - ind = (gr < 1) & (dat['imag'].values < 8) + gr = (dat.gmag - dat.rmag).values + ind = (gr < 1) & (dat.imag.values < 15) d = dat.iloc[ind] x,y = self.wcs.all_world2pix(d.RAJ2000.values,d.DEJ2000.values,0) d['col'] = x d['row'] = y - pos_ind = (-5 < x) & (x < self.ref.shape[1]+5) & (-5 < y) & (y < self.ref.shape[0]+5) + pos_ind = (5 < x) & (x < self.ref.shape[1]-5) & (5 < y) & (y < self.ref.shape[0]-5) d = d.iloc[pos_ind] - x = x[pos_ind]; y = y[pos_ind] # account for crowding for i in range(len(d)): - xx = d.col.values[i] - yy = d.row.values[i] + x = d.col.values[i] + y = d.row.values[i] - dist = np.sqrt((tab['col'].values-xx)**2 + (tab['row'].values-yy)**2) + dist = np.sqrt((tab.col.values-x)**2 + (tab.row.values-y)**2) - ind = dist < 1 + ind = dist < 1.5 close = tab.iloc[ind] d['gmag'].iloc[i] = -2.5*np.log10(np.nansum(mag2flux(close.gmag.values,25))) + 25 @@ -3516,7 +2601,6 @@ def field_calibrate(self,zp_single=True,plot=None,savename=None): d['zmag'].iloc[i] = -2.5*np.log10(np.nansum(mag2flux(close.zmag.values,25))) + 25 if system == 'ps1': d['ymag'].iloc[i] = -2.5*np.log10(np.nansum(mag2flux(close.ymag.values,25))) + 25 - # convert to tess mags if len(d) < 10: print('!!!WARNING!!! field calibration is unreliable, using the default zp = 20.44') @@ -3532,56 +2616,21 @@ def field_calibrate(self,zp_single=True,plot=None,savename=None): d = SM_to_TESS_mag(d,ebv=self.ebv) - maglim = 8.5 - maglim_bright = 10 - dist = np.sqrt((x[:,np.newaxis] - x[np.newaxis,:])**2 + (y[:,np.newaxis] - y[np.newaxis,:])**2) - mag_diff = d['tmag'].values[:,np.newaxis] - d['tmag'].values[np.newaxis,:] - mag_diff[mag_diff == 0] = np.nan - mag_diff[mag_diff < -2] = np.nan - mag_diff = np.isnan(mag_diff) - dist[dist==0] = np.nan - dist[mag_diff] = np.nan - min_dist = np.nanmin(dist,axis=1) - ind = min_dist > 5 - if sum(ind) < 10: - ind = min_dist > 3 - d = d.iloc[ind] - ind2 = (d['tmag'].values < maglim) & (d['tmag'].values > maglim_bright) - d = d.iloc[ind2] - xx = x[ind][ind2]; yy = y[ind][ind2] - ind = (xx > 5) & (xx < self.ref.shape[1]-5) & (yy > 5) & (yy < self.ref.shape[0]-5) - d = d.iloc[ind] - xx = xx[ind]; yy = yy[ind] - d['col'] = xx; d['row'] = yy - - #self.cat['cal'] = 0 - #self.cat['cal'].iloc[ind] = 1 - - if len(d) == 0: - print('!!! No suitable calibration sources !!!\nSetting to the default value of zp=20.44') - self.zp = 20.44 - self.zp_e = 0.05 - # backup for when messing around with flux later - self.tzp = 20.44 - self.tzp_e = 0.05 - return - flux = [] eflux = [] eind = np.zeros(len(d)) for i in range(len(d)): mask = np.zeros_like(self.ref) - xx = int(np.round(d['col'].values[i],0)); yy = int(np.round(d['row'].values[i])) + xx = int(d.col.values[i] + .5); yy = int(d.row.values[i] + .5) mask[yy,xx] = 1 mask = convolve(mask,np.ones((3,3))) if self.phot_method == 'aperture': flux += [np.nansum(tflux*mask,axis=(1,2))] elif self.phot_method == 'psf': - f, e = self.psf_photometry(xPix=xx,yPix=yy,snap='ref',diff=False) - flux += [f] - eflux += [e] + flux += [self.psf_photometry(xPix=xx,yPix=yy,snap='ref',diff=False)[0]] + eflux += [self.psf_photometry(xPix=xx,yPix=yy,snap='ref',diff=False)[1]] m2 = np.zeros_like(self.ref) - m2[int(np.round(d['row'].values[i],0)),int(np.round(d['col'].values[i]))] = 1 + m2[int(d.row.values[i] + .5),int(d.col.values[i] + .5)] = 1 m2 = convolve(m2,np.ones((7,7))) - convolve(m2,np.ones((5,5))) eflux += [np.nansum(tflux*m2,axis=(1,2))] mag = -2.5*np.log10(np.nansum((ref*m2))) + 20.44 @@ -3596,9 +2645,10 @@ def field_calibrate(self,zp_single=True,plot=None,savename=None): #eind = abs(eflux) > 20 if self.phot_method == 'aperture': flux[~eind] = np.nan - + #calculate the zeropoint - zp = d['tmag'].values[:,np.newaxis] + 2.5*np.log10(flux) + zp = d.tmag.values[:,np.newaxis] + 2.5*np.log10(flux) + # zp = d.tmag.values[:, np.newaxis, np.newaxis] + 2.5*np.log10(flux) if len(zp) == 0: zp = np.array([20.44]) @@ -3618,14 +2668,12 @@ def field_calibrate(self,zp_single=True,plot=None,savename=None): if plot: plt.figure() nonan = np.isfinite(self.ref) - plt.imshow(ref,origin='lower',vmax = np.percentile(ref[nonan],90),vmin=np.percentile(ref[nonan],10)) - cbar = plt.colorbar() - cbar.ax.set_ylabel('Counts',fontsize=12) - plt.plot(d.col.iloc[eind],d.row.iloc[eind],'rx') + plt.imshow(ref,origin='lower',vmax = np.percentile(ref[nonan],80),vmin=np.percentile(ref[nonan],10)) + plt.scatter(d.col.iloc[eind],d.row.iloc[eind],color='r') plt.title('Calibration sources') plt.ylabel('Row',fontsize=15) plt.xlabel('Column',fontsize=15) - + plt.colorbar() plt.show() if savename is not None: plt.savefig(savename + 'cal_sources.pdf', bbox_inches = "tight") @@ -3681,10 +2729,10 @@ def field_calibrate(self,zp_single=True,plot=None,savename=None): if compare: print('!!!WARNING!!! field calibration is unreliable, using the default zp = 20.44') self.zp = 20.44 - self.zp_e = 0.05 + self.zp_e = 0.5 # backup for when messing around with flux later self.tzp = 20.44 - self.tzp_e = 0.05 + self.tzp_e = 0.5 else: self.zp = mzp self.zp_e = stdzp @@ -3783,7 +2831,7 @@ def to_flux(self,zp=None,zp_e=0,flux_type='mjy',plot=False): zp_e = self.zp_e if flux_type.lower() == 'mjy': - flux_zp = 8.4 + flux_zp = 16.4 elif flux_type.lower() == 'jy': flux_zp = 8.9 elif (flux_type.lower() == 'erg') | (flux_type.lower() == 'cgs'): @@ -3807,7 +2855,7 @@ def to_flux(self,zp=None,zp_e=0,flux_type='mjy',plot=False): if flux_type.lower() == 'mjy': - self.zp = self.zp * 0 + 8.4 + self.zp = self.zp * 0 + 16.4 self.zp_e = 0 self.lc_units = 'mJy' if flux_type.lower() == 'jy': diff --git a/tests/test_adaptive_background.py b/tests/test_adaptive_background.py deleted file mode 100644 index a66612d..0000000 --- a/tests/test_adaptive_background.py +++ /dev/null @@ -1,163 +0,0 @@ -import unittest -import numpy as np -from numpy.testing import assert_array_equal, assert_allclose - -from tessreduce.adaptive_background import ( - _make_odd, - _get_segments, - _block_reduce, - _upsample_nearest, - adaptive_medfilt_3d, -) - - -class TestMakeOdd(unittest.TestCase): - - def test_odd_input_unchanged(self): - self.assertEqual(_make_odd(5), 5) - self.assertEqual(_make_odd(11), 11) - - def test_even_input_incremented(self): - self.assertEqual(_make_odd(4), 5) - self.assertEqual(_make_odd(10), 11) - - def test_minimum_enforced(self): - self.assertEqual(_make_odd(1), 3) - self.assertEqual(_make_odd(0), 3) - self.assertEqual(_make_odd(2), 3) - - def test_large_even(self): - self.assertEqual(_make_odd(100), 101) - - -class TestGetSegments(unittest.TestCase): - - def test_no_gap_single_segment(self): - time = np.arange(20) * 0.02 # uniform 0.02-day cadence - segs = _get_segments(time, gap_thresh=3.0) - self.assertEqual(segs, [(0, 20)]) - - def test_one_gap_two_segments(self): - t1 = np.arange(10) * 0.02 - t2 = np.arange(10) * 0.02 + 5.0 # 5-day gap - time = np.concatenate([t1, t2]) - segs = _get_segments(time, gap_thresh=3.0) - self.assertEqual(len(segs), 2) - self.assertEqual(segs[0], (0, 10)) - self.assertEqual(segs[1], (10, 20)) - - def test_two_gaps_three_segments(self): - t1 = np.arange(8) * 0.02 - t2 = np.arange(8) * 0.02 + 5.0 - t3 = np.arange(8) * 0.02 + 10.0 - time = np.concatenate([t1, t2, t3]) - segs = _get_segments(time, gap_thresh=3.0) - self.assertEqual(len(segs), 3) - - def test_segments_cover_full_range(self): - time = np.concatenate([np.arange(15) * 0.02, np.arange(15) * 0.02 + 3.0]) - segs = _get_segments(time, gap_thresh=3.0) - starts = [s for s, _ in segs] - ends = [e for _, e in segs] - self.assertEqual(starts[0], 0) - self.assertEqual(ends[-1], len(time)) - - -class TestBlockReduce(unittest.TestCase): - - def test_output_shape(self): - arr = np.ones((10, 12, 12)) - result = _block_reduce(arr, bs=4) - self.assertEqual(result.shape, (10, 3, 3)) - - def test_uniform_array_value_preserved(self): - arr = np.full((5, 8, 8), 7.0) - result = _block_reduce(arr, bs=2) - assert_allclose(result, 7.0) - - def test_dtype_preserved(self): - arr = np.ones((4, 6, 6), dtype=np.float32) - result = _block_reduce(arr, bs=3) - self.assertEqual(result.dtype, np.float32) - - def test_edge_pixels_discarded(self): - # 7 pixels with bs=3: only first 6 used → output size 2 - arr = np.ones((3, 7, 7)) - result = _block_reduce(arr, bs=3) - self.assertEqual(result.shape, (3, 2, 2)) - - -class TestUpsampleNearest(unittest.TestCase): - - def test_exact_multiple(self): - arr = np.arange(12, dtype=float).reshape(3, 2, 2) - result = _upsample_nearest(arr, X=4, Y=4, bs=2) - self.assertEqual(result.shape, (3, 4, 4)) - - def test_pads_to_target_size(self): - arr = np.ones((2, 2, 2)) - result = _upsample_nearest(arr, X=5, Y=5, bs=2) - self.assertEqual(result.shape, (2, 5, 5)) - - def test_values_tiled_correctly(self): - arr = np.array([[[1.0, 2.0], [3.0, 4.0]]]) # (1, 2, 2) - result = _upsample_nearest(arr, X=4, Y=4, bs=2) - assert_allclose(result[0, :2, :2], 1.0) - assert_allclose(result[0, :2, 2:4], 2.0) - assert_allclose(result[0, 2:4, :2], 3.0) - assert_allclose(result[0, 2:4, 2:4], 4.0) - - -class TestAdaptiveMedfilt3d(unittest.TestCase): - - def _make_cube(self, T=30, X=10, Y=10, seed=0): - rng = np.random.default_rng(seed) - return rng.normal(100.0, 5.0, (T, X, Y)).astype(np.float32) - - def test_output_shapes(self): - data = self._make_cube(T=25, X=8, Y=8) - smoothed, windows, variability, windows_pre = adaptive_medfilt_3d(data, n_jobs=1) - self.assertEqual(smoothed.shape, data.shape) - self.assertEqual(windows.shape, data.shape) - self.assertEqual(variability.shape, data.shape) - self.assertEqual(windows_pre.shape, data.shape) - - def test_constant_cube_unchanged(self): - data = np.full((20, 8, 8), 50.0, dtype=np.float32) - smoothed, *_ = adaptive_medfilt_3d(data, n_jobs=1) - assert_allclose(smoothed, 50.0, atol=1e-3) - - def test_windows_within_bounds(self): - data = self._make_cube(T=20, X=6, Y=6) - _, windows, _, _ = adaptive_medfilt_3d(data, w_min=3, w_max=11, n_jobs=1) - self.assertGreaterEqual(int(windows.min()), 3) - self.assertLessEqual(int(windows.max()), 11) - - def test_handles_nan_input(self): - data = self._make_cube(T=20, X=6, Y=6) - data[5, 3, 3] = np.nan - smoothed, *_ = adaptive_medfilt_3d(data, n_jobs=1) - self.assertEqual(smoothed.shape, data.shape) - - def test_time_array_accepted(self): - data = self._make_cube(T=20, X=6, Y=6) - time = np.arange(20) * 0.02 - smoothed, *_ = adaptive_medfilt_3d(data, time=time, n_jobs=1) - self.assertEqual(smoothed.shape, data.shape) - - def test_gradient_metric(self): - data = self._make_cube(T=20, X=6, Y=6) - smoothed, *_ = adaptive_medfilt_3d(data, metric='gradient', n_jobs=1) - self.assertEqual(smoothed.shape, data.shape) - - def test_with_gap_in_time(self): - data = self._make_cube(T=30, X=6, Y=6) - t1 = np.arange(15) * 0.02 - t2 = np.arange(15) * 0.02 + 10.0 - time = np.concatenate([t1, t2]) - smoothed, *_ = adaptive_medfilt_3d(data, time=time, n_jobs=1) - self.assertEqual(smoothed.shape, data.shape) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_cat_mask.py b/tests/test_cat_mask.py deleted file mode 100644 index 9577c86..0000000 --- a/tests/test_cat_mask.py +++ /dev/null @@ -1,223 +0,0 @@ -import unittest -import numpy as np -import pandas as pd -from numpy.testing import assert_array_equal - -from tessreduce.cat_mask import ( - size_limit, - circle_app, - ps1_auto_mask, - gaia_auto_mask, - Big_sat, - detect_straps_empirical, - Strap_mask, -) - - -def _make_catalog(xs, ys, mags): - """Build a minimal source catalog DataFrame.""" - return pd.DataFrame({'x': xs, 'y': ys, 'mag': mags}) - - -class TestSizeLimit(unittest.TestCase): - - def test_inside_pixels_true(self): - image = np.zeros((20, 20)) - x = np.array([5, 10, 15]) - y = np.array([5, 10, 15]) - ind = size_limit(x, y, image) - self.assertTrue(ind.all()) - - def test_boundary_pixels_false(self): - image = np.zeros((20, 20)) - x = np.array([0, 19, 10]) - y = np.array([10, 10, 0]) - ind = size_limit(x, y, image) - # x=0 and x=19 are at the edges, should be excluded - self.assertFalse(ind[0]) - self.assertFalse(ind[1]) - - def test_mixed(self): - image = np.zeros((10, 10)) - x = np.array([5, 0, 9]) - y = np.array([5, 5, 5]) - ind = size_limit(x, y, image) - self.assertTrue(ind[0]) - self.assertFalse(ind[1]) - self.assertFalse(ind[2]) - - -class TestCircleApp(unittest.TestCase): - - def test_output_shape(self): - mask = circle_app(5) - # shape should be roughly (2*rad+1, 2*rad+1) - self.assertEqual(mask.shape[0], mask.shape[1]) - self.assertGreater(mask.shape[0], 8) - - def test_center_is_set(self): - rad = 4 - mask = circle_app(rad) - cy, cx = mask.shape[0] // 2, mask.shape[1] // 2 - self.assertEqual(mask[cy, cx], 1) - - def test_corners_zero(self): - mask = circle_app(5) - # corners of a circular aperture should be 0 - self.assertEqual(mask[0, 0], 0) - self.assertEqual(mask[-1, -1], 0) - - def test_binary_values(self): - mask = circle_app(3) - unique = np.unique(mask) - self.assertTrue(set(unique).issubset({0, 1})) - - -class TestPs1AutoMask(unittest.TestCase): - - def _make_image(self, size=30): - return np.zeros((size, size)) - - def test_returns_dict_with_all_key(self): - image = self._make_image() - cat = _make_catalog(xs=[10, 15], ys=[10, 15], mags=[17.5, 16.5]) - masks = ps1_auto_mask(cat, image) - self.assertIn('all', masks) - - def test_output_shape_matches_image(self): - image = self._make_image(25) - cat = _make_catalog(xs=[8, 12], ys=[8, 12], mags=[15.5, 14.0]) - masks = ps1_auto_mask(cat, image) - self.assertEqual(masks['all'].shape, image.shape) - - def test_source_position_masked(self): - image = self._make_image(40) - cat = _make_catalog(xs=[20], ys=[20], mags=[16.5]) - masks = ps1_auto_mask(cat, image) - # source at (20,20) should be masked in the 'all' layer - self.assertGreater(masks['all'][20, 20], 0) - - def test_empty_catalog_all_zeros(self): - image = self._make_image() - cat = _make_catalog(xs=[], ys=[], mags=[]) - masks = ps1_auto_mask(cat, image) - assert_array_equal(masks['all'], np.zeros_like(image)) - - def test_out_of_bounds_sources_ignored(self): - image = self._make_image(20) - # sources outside image boundaries - cat = _make_catalog(xs=[100, -5], ys=[100, -5], mags=[16.0, 17.0]) - masks = ps1_auto_mask(cat, image) - assert_array_equal(masks['all'], np.zeros_like(image)) - - -class TestGaiaAutoMask(unittest.TestCase): - - def _make_image(self, size=30): - return np.zeros((size, size)) - - def test_returns_dict_with_all_key(self): - image = self._make_image() - cat = _make_catalog(xs=[10], ys=[10], mags=[14.0]) - masks = gaia_auto_mask(cat, image) - self.assertIn('all', masks) - - def test_output_shape_matches_image(self): - image = self._make_image(35) - cat = _make_catalog(xs=[15, 20], ys=[15, 20], mags=[13.0, 15.5]) - masks = gaia_auto_mask(cat, image) - self.assertEqual(masks['all'].shape, image.shape) - - def test_bright_source_masked(self): - image = self._make_image(50) - cat = _make_catalog(xs=[25], ys=[25], mags=[9.0]) - masks = gaia_auto_mask(cat, image) - self.assertGreater(masks['all'][25, 25], 0) - - def test_empty_catalog(self): - image = self._make_image() - cat = _make_catalog(xs=[], ys=[], mags=[]) - masks = gaia_auto_mask(cat, image) - assert_array_equal(masks['all'], np.zeros_like(image)) - - -class TestBigSat(unittest.TestCase): - - def test_no_saturated_stars_returns_empty(self): - image = np.zeros((50, 50)) - # all stars fainter than magnitude 7 threshold - cat = _make_catalog(xs=[20, 30], ys=[20, 30], mags=[10.0, 12.0]) - result = Big_sat(cat, image) - self.assertEqual(len(result), 0) - - def test_saturated_star_produces_mask(self): - image = np.zeros((80, 80)) - cat = _make_catalog(xs=[40], ys=[40], mags=[6.0]) - result = Big_sat(cat, image) - self.assertGreater(len(result), 0) - self.assertEqual(result[0].shape, image.shape) - # center of the saturated star should be masked - self.assertGreater(result[0][40, 40], 0) - - -class TestDetectStrapsEmpirical(unittest.TestCase): - - def _make_uniform_cube(self, T=50, X=20, Y=30, seed=0): - rng = np.random.default_rng(seed) - return rng.normal(100.0, 2.0, (T, X, Y)) - - def test_uniform_flux_no_straps(self): - cube = self._make_uniform_cube() - cols = detect_straps_empirical(cube, min_snr=5.0) - # pure noise should not trigger detections at high SNR - self.assertEqual(len(cols), 0) - - def test_elevated_column_detected(self): - rng = np.random.default_rng(1) - cube = rng.normal(100.0, 1.0, (60, 15, 25)) - # column 12 is 30% elevated in bright frames - order = np.argsort(cube.mean(axis=(1, 2))) - bright = order[-12:] - cube[np.ix_(bright, np.arange(15), [12])] *= 1.3 - cols = detect_straps_empirical(cube, min_snr=3.0) - self.assertIn(12, cols) - - def test_output_dtype_int(self): - cube = self._make_uniform_cube() - cols = detect_straps_empirical(cube) - self.assertTrue(np.issubdtype(cols.dtype, np.integer)) - - def test_detected_cols_within_bounds(self): - cube = self._make_uniform_cube(Y=20) - cols = detect_straps_empirical(cube, min_snr=1.0) - self.assertTrue(np.all(cols >= 0)) - self.assertTrue(np.all(cols < 20)) - - -class TestStrapMask(unittest.TestCase): - # col is the TPF column offset (integer). Strap positions are computed as - # straps_csv - col + 44. Strap catalogue starts at column 77, so with - # col=111 the first strap lands at pixel 77 - 111 + 44 = 10. - - def test_known_strap_column_masked(self): - # col=111 places strap columns 77,78 at pixels 10,11 inside a 30-wide image - image = np.zeros((30, 30)) - mask = Strap_mask(image, col=111, size=4) - self.assertEqual(mask.shape, image.shape) - self.assertTrue(np.any(mask > 0)) - - def test_no_straps_in_image(self): - # max strap column is 1972; col=2100 maps it to 1972-2100+44=-84 (out of range) - image = np.zeros((20, 20)) - mask = Strap_mask(image, col=2100, size=4) - self.assertEqual(mask.shape, image.shape) - self.assertEqual(mask.sum(), 0) - - def test_output_shape_matches_image(self): - image = np.zeros((25, 35)) - mask = Strap_mask(image, col=111, size=3) - self.assertEqual(mask.shape, image.shape) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_helpers.py b/tests/test_helpers.py deleted file mode 100644 index 3383134..0000000 --- a/tests/test_helpers.py +++ /dev/null @@ -1,319 +0,0 @@ -import unittest -from unittest.mock import patch -import numpy as np -from numpy.testing import assert_array_equal, assert_allclose -from astropy import units as u - -import matplotlib -matplotlib.use('Agg') - -from tessreduce.helpers import ( - strip_units, - sigma_mask, - Source_mask, - sig_err, - grads_rad, - grad_flux_rad, - image_sub, - grad_clip, - fit_strap, - Identify_masks, - Multiple_day_breaks, - smooth_zp, - Smooth_bkg, - regional_stats_mask, -) - - -class TestStripUnits(unittest.TestCase): - - def test_ndarray_passthrough(self): - arr = np.array([1.0, 2.0, 3.0]) - result = strip_units(arr) - assert_array_equal(result, arr) - self.assertIsInstance(result, np.ndarray) - - def test_astropy_quantity(self): - qty = np.array([1.0, 2.0]) * u.electron / u.s - result = strip_units(qty) - assert_array_equal(result, np.array([1.0, 2.0])) - - -class TestSigmaMask(unittest.TestCase): - - def test_masks_outlier(self): - rng = np.random.default_rng(42) - data = rng.normal(0, 1, 100) - data[50] = 1000.0 - mask = sigma_mask(data, sigma=3) - self.assertFalse(mask[50], "outlier should be masked (False)") - self.assertGreater(mask.sum(), 90) - - def test_all_finite_mostly_true(self): - data = np.ones(50) - mask = sigma_mask(data, sigma=3) - self.assertTrue(mask.all()) - - def test_returns_bool_array(self): - data = np.arange(20, dtype=float) - mask = sigma_mask(data, sigma=3) - self.assertEqual(mask.dtype, bool) - self.assertEqual(mask.shape, data.shape) - - -class TestSourceMask(unittest.TestCase): - - def test_uniform_image_no_sources(self): - data = np.ones((20, 20)) * 100.0 - mask = Source_mask(data) - # uniform image — mask should be all zeros (everything below 95th pct threshold) - self.assertEqual(mask.shape, (20, 20)) - - def test_bright_source_detected(self): - rng = np.random.default_rng(0) - data = rng.normal(100, 5, (30, 30)) - data[15, 15] = 5000.0 # bright source - mask = Source_mask(data) - self.assertEqual(mask.shape, data.shape) - # bright pixel should be masked (0) while background stays unmasked (1) - self.assertEqual(mask[15, 15], 0.0) - - def test_all_nan_returns_zeros(self): - data = np.full((10, 10), np.nan) - mask = Source_mask(data) - assert_array_equal(mask, np.zeros((10, 10))) - - -class TestSigErr(unittest.TestCase): - - def test_outlier_masked(self): - rng = np.random.default_rng(7) - data = rng.normal(0, 1, 100) - data[30] = 500.0 - mask = sig_err(data, sig=5) - self.assertTrue(mask[30]) - - def test_clean_data_no_mask(self): - data = np.zeros(50) - mask = sig_err(data, sig=5) - self.assertFalse(mask.any()) - - def test_with_error_array(self): - data = np.ones(50, dtype=float) - data[25] = 100.0 - err = np.ones(50) * 0.1 - mask = sig_err(data, err=err, sig=5) - self.assertTrue(mask[25]) - - -class TestGradsRad(unittest.TestCase): - - def test_shape_preserved(self): - flux = np.linspace(1, 10, 50) - result = grads_rad(flux) - self.assertEqual(result.shape, flux.shape) - - def test_constant_flux_near_zero(self): - flux = np.ones(50) * 5.0 - result = grads_rad(flux) - assert_allclose(result, 0.0, atol=1e-10) - - -class TestGradFluxRad(unittest.TestCase): - - def test_shape_preserved(self): - flux = np.linspace(1, 10, 30) - result = grad_flux_rad(flux) - self.assertEqual(result.shape, flux.shape) - - def test_nonnegative(self): - flux = np.linspace(0, 5, 30) - result = grad_flux_rad(flux) - self.assertTrue((result >= 0).all()) - - -class TestImageSub(unittest.TestCase): - - def test_zero_shift_returns_low_cost(self): - rng = np.random.default_rng(1) - img = rng.normal(100, 5, (30, 30)) - cost = image_sub((0.0, 0.0), img, img) - self.assertAlmostEqual(cost, 0.0, places=5) - - def test_nonzero_shift_increases_cost(self): - rng = np.random.default_rng(2) - img = rng.normal(100, 5, (30, 30)) - cost_zero = image_sub((0.0, 0.0), img, img) - cost_shifted = image_sub((3.0, 0.0), img, img) - self.assertGreater(cost_shifted, cost_zero) - - -class TestGradClip(unittest.TestCase): - - def test_clean_data_mostly_passes(self): - rng = np.random.default_rng(3) - data = rng.normal(0, 1, 200) - mask = grad_clip(data, box_size=50) - # most points should pass - self.assertGreater(mask.sum(), 150) - - def test_returns_bool(self): - data = np.linspace(0, 10, 100) - result = grad_clip(data, box_size=20) - self.assertEqual(result.dtype, bool) - self.assertEqual(result.shape, data.shape) - - def test_spike_clipped(self): - data = np.ones(100, dtype=float) - data[50] = 1000.0 - data[51] = 1000.0 - result = grad_clip(data, box_size=30) - # spike region should be clipped - self.assertFalse(result[50]) - - -class TestFitStrap(unittest.TestCase): - - def test_interpolates_over_masked_values(self): - data = np.ones(50, dtype=float) * 5.0 - data[20:25] = 200.0 - # mask marks GOOD pixels (True = usable background) - mask = data < 100.0 - result = fit_strap(data, mask) - # interpolated values in contaminated region should be near background (~5) - self.assertTrue(np.all(np.abs(result[20:25] - 5.0) < 3.0)) - - def test_returns_same_length(self): - data = np.linspace(1, 10, 40) - mask = np.ones(40, dtype=bool) - result = fit_strap(data, mask) - self.assertEqual(len(result), 40) - - def test_no_good_pixels_returns_ones(self): - data = np.ones(20, dtype=float) * 5.0 - mask = np.zeros(20, dtype=bool) # no good pixels - result = fit_strap(data, mask) - self.assertEqual(len(result), 20) - - -class TestIdentifyMasks(unittest.TestCase): - - def test_two_islands(self): - obj = np.array([0, 1, 1, 0, 0, 1, 0], dtype=float) - masks = Identify_masks(obj) - self.assertEqual(len(masks), 2) - # first island spans indices 1-2 - self.assertTrue(masks[0][1]) - self.assertTrue(masks[0][2]) - self.assertFalse(masks[0][5]) - # second island is index 5 - self.assertTrue(masks[1][5]) - - def test_single_island(self): - obj = np.array([0, 0, 1, 1, 1, 0, 0], dtype=float) - masks = Identify_masks(obj) - self.assertEqual(len(masks), 1) - self.assertTrue(masks[0][2]) - self.assertTrue(masks[0][4]) - - def test_empty_returns_empty(self): - obj = np.zeros(10, dtype=float) - masks = Identify_masks(obj) - self.assertEqual(len(masks), 0) - - -class TestMultipleDayBreaks(unittest.TestCase): - - def _make_lc(self, times, flux=None): - if flux is None: - flux = np.ones_like(times) - return np.array([times, flux]) - - def test_no_gap_two_endpoints(self): - times = np.arange(10) * 0.02 # cadence 0.02 days, no gap - lc = self._make_lc(times) - breaks = Multiple_day_breaks(lc) - assert_array_equal(breaks, [0, len(times)]) - - def test_one_gap_three_segments(self): - times = np.concatenate([np.arange(5) * 0.02, np.arange(5) * 0.02 + 2.0]) - lc = self._make_lc(times) - breaks = Multiple_day_breaks(lc) - self.assertEqual(len(breaks), 3) - self.assertEqual(breaks[0], 0) - self.assertEqual(breaks[-1], len(times)) - - def test_nan_flux_excluded_from_break_detection(self): - times = np.concatenate([np.arange(5) * 0.02, np.arange(5) * 0.02 + 2.0]) - flux = np.ones(10) - flux[3] = np.nan # NaN does not create a break - lc = self._make_lc(times, flux) - breaks = Multiple_day_breaks(lc) - self.assertGreater(len(breaks), 2) - - -class TestSmoothZp(unittest.TestCase): - - @patch('tessreduce.helpers.plt.figure') - @patch('tessreduce.helpers.plt.plot') - def test_returns_smoothed_and_err(self, _mock_plot, _mock_figure): - rng = np.random.default_rng(5) - N = 60 - time = np.arange(N) * 0.02 - zp = np.ones(N) * 25.0 + rng.normal(0, 0.05, N) - smoothed, err = smooth_zp(zp, time) - self.assertEqual(smoothed.shape, zp.shape) - self.assertIsInstance(err, float) - self.assertGreaterEqual(err, 0.0) - - @patch('tessreduce.helpers.plt.figure') - @patch('tessreduce.helpers.plt.plot') - def test_two_segment_sector(self, _mock_plot, _mock_figure): - N = 60 - t1 = np.arange(30) * 0.02 - t2 = np.arange(30) * 0.02 + 14.0 # 14-day gap - time = np.concatenate([t1, t2]) - zp = np.ones(N) * 25.0 - smoothed, err = smooth_zp(zp, time) - self.assertEqual(smoothed.shape, (N,)) - - -class TestSmoothBkg(unittest.TestCase): - - def test_all_nan_returns_zeros(self): - data = np.full((10, 10), np.nan) - result = Smooth_bkg(data) - assert_array_equal(result, np.zeros((10, 10))) - - def test_output_shape(self): - rng = np.random.default_rng(9) - data = rng.normal(100, 5, (15, 15)) - data[5:8, 5:8] = np.nan - result = Smooth_bkg(data, interpolate=True) - self.assertEqual(result.shape, data.shape) - - def test_finite_output_for_finite_input(self): - data = np.ones((12, 12)) * 50.0 - result = Smooth_bkg(data, interpolate=True) - self.assertTrue(np.all(np.isfinite(result))) - - -class TestRegionalStatsMask(unittest.TestCase): - - def test_output_shape_and_dtype(self): - rng = np.random.default_rng(11) - image = rng.normal(100, 5, (30, 30)) - mask = regional_stats_mask(image, size=15, sigma=3) - self.assertEqual(mask.shape, image.shape) - self.assertTrue(np.issubdtype(mask.dtype, np.number)) - self.assertTrue(set(np.unique(mask)).issubset({0, 1, 0.0, 1.0})) - - def test_outlier_masked(self): - image = np.ones((30, 30)) * 100.0 - image[15, 15] = 50000.0 - mask = regional_stats_mask(image, size=15, sigma=3) - self.assertTrue(mask[15, 15]) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_rescale_straps.py b/tests/test_rescale_straps.py deleted file mode 100644 index 5c0b7f7..0000000 --- a/tests/test_rescale_straps.py +++ /dev/null @@ -1,113 +0,0 @@ -import unittest -import numpy as np -from numpy.testing import assert_allclose, assert_array_equal - -from tessreduce.rescale_straps import grad_clip, fit_strap, correct_straps - - -class TestGradClip(unittest.TestCase): - - def test_returns_bool_correct_shape(self): - data = np.linspace(0, 10, 120) - result = grad_clip(data, box_size=30) - self.assertEqual(result.dtype, bool) - self.assertEqual(result.shape, data.shape) - - def test_smooth_data_mostly_passes(self): - data = np.ones(150) - result = grad_clip(data, box_size=50) - self.assertGreater(result.sum(), 100) - - def test_spike_flagged(self): - data = np.ones(100, dtype=float) - data[50] = 500.0 - data[51] = 500.0 - result = grad_clip(data, box_size=30) - self.assertFalse(result[50]) - - def test_handles_nans(self): - data = np.ones(100, dtype=float) - data[20:25] = np.nan - result = grad_clip(data, box_size=30) - self.assertEqual(result.shape, data.shape) - - -class TestFitStrap(unittest.TestCase): - - def test_returns_correct_length(self): - data = np.linspace(1, 5, 50) - result = fit_strap(data, percentile=20) - self.assertEqual(len(result), 50) - - def test_high_values_replaced_by_interpolation(self): - # Background at 5, stellar contamination spikes at 200 - data = np.ones(60, dtype=float) * 5.0 - data[25:30] = 200.0 - result = fit_strap(data, percentile=20) - # contaminated region should be near background level after interpolation - finite = np.isfinite(result[25:30]) - if finite.any(): - self.assertTrue(np.all(result[25:30][finite] < 50.0)) - - def test_all_nan_returns_nan(self): - data = np.full(20, np.nan) - result = fit_strap(data) - self.assertEqual(len(result), 20) - self.assertTrue(np.all(np.isnan(result))) - - def test_mostly_nan_returns_nan(self): - data = np.full(20, np.nan) - data[0] = 1.0 - data[1] = 2.0 # fewer than 5 finite → returns nan array - result = fit_strap(data) - self.assertTrue(np.all(np.isnan(result))) - - -class TestCorrectStraps(unittest.TestCase): - - def _make_flat_image(self, rows=30, cols=30, value=100.0): - return np.full((rows, cols), value, dtype=float) - - def _make_strap_mask(self, rows, cols, strap_cols): - """bit 2 (value 4) flags strap columns.""" - mask = np.zeros((rows, cols), dtype=int) - for c in strap_cols: - mask[:, c] = 4 - return mask - - def test_no_strap_cols_returns_ones(self): - img = self._make_flat_image() - mask = np.zeros((30, 30), dtype=int) # no strap bits set - qe = correct_straps(img, mask, av_size=3, parallel=False) - # with no straps, returns all-ones correction - assert_allclose(qe, np.ones((30, 30)), atol=1e-6) - - def test_output_shape_matches_input(self): - img = self._make_flat_image(25, 40) - mask = self._make_strap_mask(25, 40, strap_cols=[10, 11]) - qe = correct_straps(img, mask, av_size=3, parallel=False) - self.assertEqual(qe.shape, img.shape) - - def test_strap_correction_near_one_for_flat_image(self): - # uniform image: strap column has same flux as neighbours → factor ≈ 1 - img = self._make_flat_image(40, 40, value=200.0) - mask = self._make_strap_mask(40, 40, strap_cols=[20]) - qe = correct_straps(img, mask, av_size=5, parallel=False) - # QE factor for a uniform image should be close to 1 - finite_qe = qe[np.isfinite(qe)] - self.assertTrue(np.all(np.abs(finite_qe - 1.0) < 0.5)) - - def test_elevated_strap_returns_factor_greater_than_one(self): - # strap column 20% brighter than neighbours → factor ≈ 1/1.2 - rows, cols = 50, 30 - img = np.ones((rows, cols), dtype=float) * 100.0 - img[:, 15] = 120.0 # strap column 20% elevated - mask = self._make_strap_mask(rows, cols, strap_cols=[15]) - qe = correct_straps(img, mask, av_size=4, parallel=False) - # correction factor for elevated strap should be < 1 (scales it down) - col_factor = np.nanmedian(qe[:, 15]) - self.assertLess(col_factor, 1.1) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_tessreduce_main.py b/tests/test_tessreduce_main.py index 0870f1b..515679e 100755 --- a/tests/test_tessreduce_main.py +++ b/tests/test_tessreduce_main.py @@ -1,145 +1,40 @@ -""" -Integration tests for the tessreduce pipeline. - -These tests require a live internet connection to download TESS data from MAST. -They are skipped by default and must be opted into by setting the environment -variable TESS_INTEGRATION=1. - - TESS_INTEGRATION=1 python -m pytest tests/test_tessreduce_main.py -v -""" -import os import unittest -import numpy as np - -import matplotlib -matplotlib.use('Agg') - import tessreduce as tr -_RUN_INTEGRATION = bool(os.environ.get('TESS_INTEGRATION')) - -# Coordinates and sector used for all integration tests -_RA = 10.127 -_DEC = -50.687 -_SECTOR = 2 - - -@unittest.skipUnless(_RUN_INTEGRATION, 'set TESS_INTEGRATION=1 to run network tests') -class TestTESSreducePipeline(unittest.TestCase): - """End-to-end integration tests that download real TESS data.""" +class TestTESSreduce(unittest.TestCase): @classmethod def setUpClass(cls): - tess = tr.tessreduce(ra=_RA, dec=_DEC, sector=_SECTOR, reduce=False) + """ Initial setup run only once before all the tests + """ + + ra = 10.127#189.1385817 + dec = -50.687#11.2316535 + sector = 2 + tess = tr.tessreduce(ra=ra, dec=dec, sector=sector, reduce=False) tess.get_ref() cls.tess = tess - # ── data structure ───────────────────────────────────────────────────────── - - def test_flux_cube_shape(self): - flux = self.tess.flux - self.assertEqual(flux.ndim, 3, "flux should be a 3-D (T, X, Y) array") - T, X, Y = flux.shape - self.assertGreater(T, 0) - self.assertGreater(X, 0) - self.assertGreater(Y, 0) - - def test_ref_frame_shape_matches_flux(self): - ref = self.tess.ref - _, X, Y = self.tess.flux.shape - self.assertEqual(ref.shape, (X, Y)) - - def test_time_array_length_matches_flux(self): - T = self.tess.flux.shape[0] - self.assertEqual(len(self.tess.tpf.time), T) - - # ── make_mask ────────────────────────────────────────────────────────────── - - def test_make_mask_shape(self): + def test_Make_mask(self): self.tess.make_mask() - mask = self.tess.mask - _, X, Y = self.tess.flux.shape - self.assertEqual(mask.shape, (X, Y), - "mask should be 2-D and match the spatial dimensions of flux") - - def test_make_mask_integer_bits(self): - mask = self.tess.mask - self.assertTrue(np.issubdtype(mask.dtype, np.integer) or - np.issubdtype(mask.dtype, np.floating), - "mask values should be numeric bitmask integers") - - # ── background ───────────────────────────────────────────────────────────── - def test_background_shape(self): + def test_background(self): self.tess.background() - bkg = self.tess.bkg - self.assertEqual(bkg.shape, self.tess.flux.shape, - "background cube should match flux cube shape") - - def test_background_finite_values(self): - bkg = self.tess.bkg - finite_frac = np.isfinite(bkg).mean() - self.assertGreater(finite_frac, 0.5, "most background pixels should be finite") - - def test_background_magnitude_reasonable(self): - # TESS background is typically in the hundreds to low thousands of e-/s - median_bkg = np.nanmedian(self.tess.bkg) - self.assertGreater(median_bkg, 0, "median background should be positive") - - # ── alignment ────────────────────────────────────────────────────────────── - def test_fit_shift_shape(self): + def test_align(self): self.tess.fit_shift() - shifts = self.tess.shift - T = self.tess.flux.shape[0] - self.assertEqual(shifts.shape, (T, 2), - "shift array should be (T, 2) — one (dx, dy) per frame") - - def test_fit_shift_magnitude_reasonable(self): - # TESS pointing jitter is typically sub-pixel (< 2 px) - shift_rms = np.sqrt(np.nanmean(self.tess.shift ** 2)) - self.assertLess(shift_rms, 5.0, - "RMS shift larger than 5 px suggests alignment failure") - - # ── difference light curve ───────────────────────────────────────────────── - - def test_diff_lc_returns_three_arrays(self): - result = self.tess.diff_lc() - self.assertEqual(len(result), 3, - "diff_lc should return (time, flux, sky)") - - def test_diff_lc_time_flux_same_length(self): - time, flux, sky = self.tess.diff_lc() - self.assertEqual(len(time), len(flux)) - self.assertEqual(len(time), len(sky)) - - def test_diff_lc_time_monotonic(self): - time, _, _ = self.tess.diff_lc() - self.assertTrue(np.all(np.diff(time[np.isfinite(time)]) > 0), - "time array should be monotonically increasing") - - # ── full reduce ──────────────────────────────────────────────────────────── - def test_reduce_populates_lc(self): - tess = tr.tessreduce(ra=_RA, dec=_DEC, sector=_SECTOR) - self.assertIsNotNone(tess.lc, - "reduce() should populate the lc attribute") + #def test_Shift_images(self): + # self.tess.shift_images() - def test_reduce_lc_shape(self): - tess = tr.tessreduce(ra=_RA, dec=_DEC, sector=_SECTOR) - lc = tess.lc - # lc is expected to be (2, T) or (3, T): [time, flux] or [time, flux, err] - self.assertGreaterEqual(lc.shape[0], 2) - T = tess.flux.shape[0] - self.assertEqual(lc.shape[1], T) + def test_field_calibrate(self): + self.tess.field_calibrate() - def test_reduce_lc_time_reasonable(self): - tess = tr.tessreduce(ra=_RA, dec=_DEC, sector=_SECTOR) - time = tess.lc[0] - # TESS BTJD for sector 2 is in the range 1356–1382 - self.assertGreater(np.nanmedian(time), 1000, - "light curve time axis does not look like BTJD") + def test_Diff_lc(self): + self.tess.diff_lc() + def test_full(self): + self.tess.reduce() if __name__ == '__main__': unittest.main()